1//= unittests/ASTMatchers/ASTMatchersTraversalTest.cpp - matchers unit tests =//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "ASTMatchersTest.h"
10#include "clang/AST/PrettyPrinter.h"
11#include "clang/ASTMatchers/ASTMatchFinder.h"
12#include "clang/ASTMatchers/ASTMatchers.h"
13#include "clang/Tooling/Tooling.h"
14#include "llvm/ADT/Triple.h"
15#include "llvm/Support/Host.h"
16#include "gtest/gtest.h"
17
18namespace clang {
19namespace ast_matchers {
20
21TEST(DeclarationMatcher, hasMethod) {
22 EXPECT_TRUE(matches("class A { void func(); };",
23 cxxRecordDecl(hasMethod(hasName("func")))));
24 EXPECT_TRUE(notMatches("class A { void func(); };",
25 cxxRecordDecl(hasMethod(isPublic()))));
26}
27
28TEST(DeclarationMatcher, ClassDerivedFromDependentTemplateSpecialization) {
29 EXPECT_TRUE(matches(
30 "template <typename T> struct A {"
31 " template <typename T2> struct F {};"
32 "};"
33 "template <typename T> struct B : A<T>::template F<T> {};"
34 "B<int> b;",
35 cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl()))));
36}
37
38TEST(DeclarationMatcher, hasDeclContext) {
39 EXPECT_TRUE(matches(
40 "namespace N {"
41 " namespace M {"
42 " class D {};"
43 " }"
44 "}",
45 recordDecl(hasDeclContext(namespaceDecl(hasName("M"))))));
46 EXPECT_TRUE(notMatches(
47 "namespace N {"
48 " namespace M {"
49 " class D {};"
50 " }"
51 "}",
52 recordDecl(hasDeclContext(namespaceDecl(hasName("N"))))));
53
54 EXPECT_TRUE(matches("namespace {"
55 " namespace M {"
56 " class D {};"
57 " }"
58 "}",
59 recordDecl(hasDeclContext(namespaceDecl(
60 hasName("M"), hasDeclContext(namespaceDecl()))))));
61
62 EXPECT_TRUE(matches("class D{};", decl(hasDeclContext(decl()))));
63}
64
65TEST(HasDescendant, MatchesDescendantTypes) {
66 EXPECT_TRUE(matches("void f() { int i = 3; }",
67 decl(hasDescendant(loc(builtinType())))));
68 EXPECT_TRUE(matches("void f() { int i = 3; }",
69 stmt(hasDescendant(builtinType()))));
70
71 EXPECT_TRUE(matches("void f() { int i = 3; }",
72 stmt(hasDescendant(loc(builtinType())))));
73 EXPECT_TRUE(matches("void f() { int i = 3; }",
74 stmt(hasDescendant(qualType(builtinType())))));
75
76 EXPECT_TRUE(notMatches("void f() { float f = 2.0f; }",
77 stmt(hasDescendant(isInteger()))));
78
79 EXPECT_TRUE(matchAndVerifyResultTrue(
80 "void f() { int a; float c; int d; int e; }",
81 functionDecl(forEachDescendant(
82 varDecl(hasDescendant(isInteger())).bind("x"))),
83 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 3)));
84}
85
86TEST(HasDescendant, MatchesDescendantsOfTypes) {
87 EXPECT_TRUE(matches("void f() { int*** i; }",
88 qualType(hasDescendant(builtinType()))));
89 EXPECT_TRUE(matches("void f() { int*** i; }",
90 qualType(hasDescendant(
91 pointerType(pointee(builtinType()))))));
92 EXPECT_TRUE(matches("void f() { int*** i; }",
93 typeLoc(hasDescendant(loc(builtinType())))));
94
95 EXPECT_TRUE(matchAndVerifyResultTrue(
96 "void f() { int*** i; }",
97 qualType(asString("int ***"), forEachDescendant(pointerType().bind("x"))),
98 std::make_unique<VerifyIdIsBoundTo<Type>>("x", 2)));
99}
100
101
102TEST(Has, MatchesChildrenOfTypes) {
103 EXPECT_TRUE(matches("int i;",
104 varDecl(hasName("i"), has(isInteger()))));
105 EXPECT_TRUE(notMatches("int** i;",
106 varDecl(hasName("i"), has(isInteger()))));
107 EXPECT_TRUE(matchAndVerifyResultTrue(
108 "int (*f)(float, int);",
109 qualType(functionType(), forEach(qualType(isInteger()).bind("x"))),
110 std::make_unique<VerifyIdIsBoundTo<QualType>>("x", 2)));
111}
112
113TEST(Has, MatchesChildTypes) {
114 EXPECT_TRUE(matches(
115 "int* i;",
116 varDecl(hasName("i"), hasType(qualType(has(builtinType()))))));
117 EXPECT_TRUE(notMatches(
118 "int* i;",
119 varDecl(hasName("i"), hasType(qualType(has(pointerType()))))));
120}
121
122TEST(StatementMatcher, Has) {
123 StatementMatcher HasVariableI =
124 expr(hasType(pointsTo(recordDecl(hasName("X")))),
125 has(ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("i")))))));
126
127 EXPECT_TRUE(matches(
128 "class X; X *x(int); void c() { int i; x(i); }", HasVariableI));
129 EXPECT_TRUE(notMatches(
130 "class X; X *x(int); void c() { int i; x(42); }", HasVariableI));
131}
132
133TEST(StatementMatcher, HasDescendant) {
134 StatementMatcher HasDescendantVariableI =
135 expr(hasType(pointsTo(recordDecl(hasName("X")))),
136 hasDescendant(declRefExpr(to(varDecl(hasName("i"))))));
137
138 EXPECT_TRUE(matches(
139 "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }",
140 HasDescendantVariableI));
141 EXPECT_TRUE(notMatches(
142 "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }",
143 HasDescendantVariableI));
144}
145
146TEST(TypeMatcher, MatchesClassType) {
147 TypeMatcher TypeA = hasDeclaration(recordDecl(hasName("A")));
148
149 EXPECT_TRUE(matches("class A { public: A *a; };", TypeA));
150 EXPECT_TRUE(notMatches("class A {};", TypeA));
151
152 TypeMatcher TypeDerivedFromA =
153 hasDeclaration(cxxRecordDecl(isDerivedFrom("A")));
154
155 EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };",
156 TypeDerivedFromA));
157 EXPECT_TRUE(notMatches("class A {};", TypeA));
158
159 TypeMatcher TypeAHasClassB = hasDeclaration(
160 recordDecl(hasName("A"), has(recordDecl(hasName("B")))));
161
162 EXPECT_TRUE(
163 matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
164
165 EXPECT_TRUE(matchesC("struct S {}; void f(void) { struct S s; }",
166 varDecl(hasType(namedDecl(hasName("S"))))));
167}
168
169TEST(TypeMatcher, MatchesDeclTypes) {
170 // TypedefType -> TypedefNameDecl
171 EXPECT_TRUE(matches("typedef int I; void f(I i);",
172 parmVarDecl(hasType(namedDecl(hasName("I"))))));
173 // ObjCObjectPointerType
174 EXPECT_TRUE(matchesObjC("@interface Foo @end void f(Foo *f);",
175 parmVarDecl(hasType(objcObjectPointerType()))));
176 // ObjCObjectPointerType -> ObjCInterfaceType -> ObjCInterfaceDecl
177 EXPECT_TRUE(matchesObjC(
178 "@interface Foo @end void f(Foo *f);",
179 parmVarDecl(hasType(pointsTo(objcInterfaceDecl(hasName("Foo")))))));
180 // TemplateTypeParmType
181 EXPECT_TRUE(matches("template <typename T> void f(T t);",
182 parmVarDecl(hasType(templateTypeParmType()))));
183 // TemplateTypeParmType -> TemplateTypeParmDecl
184 EXPECT_TRUE(matches("template <typename T> void f(T t);",
185 parmVarDecl(hasType(namedDecl(hasName("T"))))));
186 // InjectedClassNameType
187 EXPECT_TRUE(matches("template <typename T> struct S {"
188 " void f(S s);"
189 "};",
190 parmVarDecl(hasType(injectedClassNameType()))));
191 EXPECT_TRUE(notMatches("template <typename T> struct S {"
192 " void g(S<T> s);"
193 "};",
194 parmVarDecl(hasType(injectedClassNameType()))));
195 // InjectedClassNameType -> CXXRecordDecl
196 EXPECT_TRUE(matches("template <typename T> struct S {"
197 " void f(S s);"
198 "};",
199 parmVarDecl(hasType(namedDecl(hasName("S"))))));
200
201 static const char Using[] = "template <typename T>"
202 "struct Base {"
203 " typedef T Foo;"
204 "};"
205 ""
206 "template <typename T>"
207 "struct S : private Base<T> {"
208 " using typename Base<T>::Foo;"
209 " void f(Foo);"
210 "};";
211 // UnresolvedUsingTypenameDecl
212 EXPECT_TRUE(matches(Using, unresolvedUsingTypenameDecl(hasName("Foo"))));
213 // UnresolvedUsingTypenameType -> UnresolvedUsingTypenameDecl
214 EXPECT_TRUE(matches(Using, parmVarDecl(hasType(namedDecl(hasName("Foo"))))));
215}
216
217TEST(HasDeclaration, HasDeclarationOfEnumType) {
218 EXPECT_TRUE(matches("enum X {}; void y(X *x) { x; }",
219 expr(hasType(pointsTo(
220 qualType(hasDeclaration(enumDecl(hasName("X")))))))));
221}
222
223TEST(HasDeclaration, HasGetDeclTraitTest) {
224 static_assert(internal::has_getDecl<TypedefType>::value,
225 "Expected TypedefType to have a getDecl.");
226 static_assert(internal::has_getDecl<RecordType>::value,
227 "Expected RecordType to have a getDecl.");
228 static_assert(!internal::has_getDecl<TemplateSpecializationType>::value,
229 "Expected TemplateSpecializationType to *not* have a getDecl.");
230}
231
232TEST(HasDeclaration, ElaboratedType) {
233 EXPECT_TRUE(matches(
234 "namespace n { template <typename T> struct X {}; }"
235 "void f(n::X<int>);",
236 parmVarDecl(hasType(qualType(hasDeclaration(cxxRecordDecl()))))));
237 EXPECT_TRUE(matches(
238 "namespace n { template <typename T> struct X {}; }"
239 "void f(n::X<int>);",
240 parmVarDecl(hasType(elaboratedType(hasDeclaration(cxxRecordDecl()))))));
241}
242
243TEST(HasDeclaration, HasDeclarationOfTypeWithDecl) {
244 EXPECT_TRUE(matches("typedef int X; X a;",
245 varDecl(hasName("a"),
246 hasType(typedefType(hasDeclaration(decl()))))));
247
248 // FIXME: Add tests for other types with getDecl() (e.g. RecordType)
249}
250
251TEST(HasDeclaration, HasDeclarationOfTemplateSpecializationType) {
252 EXPECT_TRUE(matches("template <typename T> class A {}; A<int> a;",
253 varDecl(hasType(templateSpecializationType(
254 hasDeclaration(namedDecl(hasName("A"))))))));
255 EXPECT_TRUE(matches("template <typename T> class A {};"
256 "template <typename T> class B { A<T> a; };",
257 fieldDecl(hasType(templateSpecializationType(
258 hasDeclaration(namedDecl(hasName("A"))))))));
259 EXPECT_TRUE(matches("template <typename T> class A {}; A<int> a;",
260 varDecl(hasType(templateSpecializationType(
261 hasDeclaration(cxxRecordDecl()))))));
262}
263
264TEST(HasDeclaration, HasDeclarationOfCXXNewExpr) {
265 EXPECT_TRUE(
266 matches("int *A = new int();",
267 cxxNewExpr(hasDeclaration(functionDecl(parameterCountIs(1))))));
268}
269
270TEST(HasDeclaration, HasDeclarationOfTypeAlias) {
271 EXPECT_TRUE(matches("template <typename T> using C = T; C<int> c;",
272 varDecl(hasType(templateSpecializationType(
273 hasDeclaration(typeAliasTemplateDecl()))))));
274}
275
276TEST(HasUnqualifiedDesugaredType, DesugarsUsing) {
277 EXPECT_TRUE(
278 matches("struct A {}; using B = A; B b;",
279 varDecl(hasType(hasUnqualifiedDesugaredType(recordType())))));
280 EXPECT_TRUE(
281 matches("struct A {}; using B = A; using C = B; C b;",
282 varDecl(hasType(hasUnqualifiedDesugaredType(recordType())))));
283}
284
285TEST(HasUnderlyingDecl, Matches) {
286 EXPECT_TRUE(matches("namespace N { template <class T> void f(T t); }"
287 "template <class T> void g() { using N::f; f(T()); }",
288 unresolvedLookupExpr(hasAnyDeclaration(
289 namedDecl(hasUnderlyingDecl(hasName("::N::f")))))));
290 EXPECT_TRUE(matches(
291 "namespace N { template <class T> void f(T t); }"
292 "template <class T> void g() { N::f(T()); }",
293 unresolvedLookupExpr(hasAnyDeclaration(namedDecl(hasName("::N::f"))))));
294 EXPECT_TRUE(notMatches(
295 "namespace N { template <class T> void f(T t); }"
296 "template <class T> void g() { using N::f; f(T()); }",
297 unresolvedLookupExpr(hasAnyDeclaration(namedDecl(hasName("::N::f"))))));
298}
299
300TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
301 TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
302 EXPECT_TRUE(
303 matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
304 EXPECT_TRUE(
305 notMatches("class X {}; void y(X *x) { x; }",
306 expr(hasType(ClassX))));
307 EXPECT_TRUE(
308 matches("class X {}; void y(X *x) { x; }",
309 expr(hasType(pointsTo(ClassX)))));
310}
311
312TEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
313 TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
314 EXPECT_TRUE(
315 matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
316 EXPECT_TRUE(
317 notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
318 EXPECT_TRUE(
319 matches("class X {}; void y() { X *x; }",
320 varDecl(hasType(pointsTo(ClassX)))));
321}
322
323TEST(HasType, TakesDeclMatcherAndMatchesExpr) {
324 DeclarationMatcher ClassX = recordDecl(hasName("X"));
325 EXPECT_TRUE(
326 matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
327 EXPECT_TRUE(
328 notMatches("class X {}; void y(X *x) { x; }",
329 expr(hasType(ClassX))));
330}
331
332TEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
333 DeclarationMatcher ClassX = recordDecl(hasName("X"));
334 EXPECT_TRUE(
335 matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
336 EXPECT_TRUE(
337 notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
338}
339
340TEST(HasType, MatchesTypedefDecl) {
341 EXPECT_TRUE(matches("typedef int X;", typedefDecl(hasType(asString("int")))));
342 EXPECT_TRUE(matches("typedef const int T;",
343 typedefDecl(hasType(asString("const int")))));
344 EXPECT_TRUE(notMatches("typedef const int T;",
345 typedefDecl(hasType(asString("int")))));
346 EXPECT_TRUE(matches("typedef int foo; typedef foo bar;",
347 typedefDecl(hasType(asString("foo")), hasName("bar"))));
348}
349
350TEST(HasType, MatchesTypedefNameDecl) {
351 EXPECT_TRUE(matches("using X = int;", typedefNameDecl(hasType(asString("int")))));
352 EXPECT_TRUE(matches("using T = const int;",
353 typedefNameDecl(hasType(asString("const int")))));
354 EXPECT_TRUE(notMatches("using T = const int;",
355 typedefNameDecl(hasType(asString("int")))));
356 EXPECT_TRUE(matches("using foo = int; using bar = foo;",
357 typedefNameDecl(hasType(asString("foo")), hasName("bar"))));
358}
359
360TEST(HasTypeLoc, MatchesDeclaratorDecls) {
361 EXPECT_TRUE(matches("int x;",
362 varDecl(hasName("x"), hasTypeLoc(loc(asString("int"))))));
363
364 // Make sure we don't crash on implicit constructors.
365 EXPECT_TRUE(notMatches("class X {}; X x;",
366 declaratorDecl(hasTypeLoc(loc(asString("int"))))));
367}
368
369
370TEST(Callee, MatchesDeclarations) {
371 StatementMatcher CallMethodX = callExpr(callee(cxxMethodDecl(hasName("x"))));
372
373 EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
374 EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
375
376 CallMethodX = traverse(TK_AsIs, callExpr(callee(cxxConversionDecl())));
377 EXPECT_TRUE(
378 matches("struct Y { operator int() const; }; int i = Y();", CallMethodX));
379 EXPECT_TRUE(notMatches("struct Y { operator int() const; }; Y y = Y();",
380 CallMethodX));
381}
382
383TEST(Callee, MatchesMemberExpressions) {
384 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
385 callExpr(callee(memberExpr()))));
386 EXPECT_TRUE(
387 notMatches("class Y { void x() { this->x(); } };", callExpr(callee(callExpr()))));
388}
389
390TEST(Matcher, Argument) {
391 StatementMatcher CallArgumentY = callExpr(
392 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
393
394 EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
395 EXPECT_TRUE(
396 matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
397 EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
398
399 StatementMatcher WrongIndex = callExpr(
400 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
401 EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
402}
403
404TEST(Matcher, AnyArgument) {
405 auto HasArgumentY = hasAnyArgument(
406 ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y"))))));
407 StatementMatcher CallArgumentY = callExpr(HasArgumentY);
408 StatementMatcher CtorArgumentY = cxxConstructExpr(HasArgumentY);
409 StatementMatcher UnresolvedCtorArgumentY =
410 cxxUnresolvedConstructExpr(HasArgumentY);
411 StatementMatcher ObjCCallArgumentY = objcMessageExpr(HasArgumentY);
412 EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
413 EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
414 EXPECT_TRUE(matches("struct Y { Y(int, int); };"
415 "void x() { int y; (void)Y(1, y); }",
416 CtorArgumentY));
417 EXPECT_TRUE(matches("struct Y { Y(int, int); };"
418 "void x() { int y; (void)Y(y, 42); }",
419 CtorArgumentY));
420 EXPECT_TRUE(matches("template <class Y> void x() { int y; (void)Y(1, y); }",
421 UnresolvedCtorArgumentY));
422 EXPECT_TRUE(matches("template <class Y> void x() { int y; (void)Y(y, 42); }",
423 UnresolvedCtorArgumentY));
424 EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) y; @end "
425 "void x(I* i) { int y; [i f:y]; }",
426 ObjCCallArgumentY));
427 EXPECT_FALSE(matchesObjC("@interface I -(void)f:(int) z; @end "
428 "void x(I* i) { int z; [i f:z]; }",
429 ObjCCallArgumentY));
430 EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
431 EXPECT_TRUE(notMatches("struct Y { Y(int, int); };"
432 "void x() { int y; (void)Y(1, 2); }",
433 CtorArgumentY));
434 EXPECT_TRUE(notMatches("template <class Y>"
435 "void x() { int y; (void)Y(1, 2); }",
436 UnresolvedCtorArgumentY));
437
438 StatementMatcher ImplicitCastedArgument =
439 traverse(TK_AsIs, callExpr(hasAnyArgument(implicitCastExpr())));
440 EXPECT_TRUE(matches("void x(long) { int y; x(y); }", ImplicitCastedArgument));
441}
442
443TEST(Matcher, HasReceiver) {
444 EXPECT_TRUE(matchesObjC(
445 "@interface NSString @end "
446 "void f(NSString *x) {"
447 "[x containsString];"
448 "}",
449 objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))));
450
451 EXPECT_FALSE(matchesObjC(
452 "@interface NSString +(NSString *) stringWithFormat; @end "
453 "void f() { [NSString stringWithFormat]; }",
454 objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))));
455}
456
457TEST(Matcher, HasAnyCapture) {
458 auto HasCaptureX = lambdaExpr(hasAnyCapture(varDecl(hasName("x"))));
459 EXPECT_TRUE(matches("void f() { int x = 3; [x](){}; }", HasCaptureX));
460 EXPECT_TRUE(matches("void f() { int x = 3; [&x](){}; }", HasCaptureX));
461 EXPECT_TRUE(notMatches("void f() { [](){}; }", HasCaptureX));
462 EXPECT_TRUE(notMatches("void f() { int z = 3; [&z](){}; }", HasCaptureX));
463 EXPECT_TRUE(
464 notMatches("struct a { void f() { [this](){}; }; };", HasCaptureX));
465}
466
467TEST(Matcher, CapturesThis) {
468 auto HasCaptureThis = lambdaExpr(hasAnyCapture(cxxThisExpr()));
469 EXPECT_TRUE(
470 matches("struct a { void f() { [this](){}; }; };", HasCaptureThis));
471 EXPECT_TRUE(notMatches("void f() { [](){}; }", HasCaptureThis));
472 EXPECT_TRUE(notMatches("void f() { int x = 3; [x](){}; }", HasCaptureThis));
473 EXPECT_TRUE(notMatches("void f() { int x = 3; [&x](){}; }", HasCaptureThis));
474 EXPECT_TRUE(notMatches("void f() { int z = 3; [&z](){}; }", HasCaptureThis));
475}
476
477TEST(Matcher, MatchesMethodsOnLambda) {
478 StringRef Code = R"cpp(
479struct A {
480 ~A() {}
481};
482void foo()
483{
484 A a;
485 auto l = [a] { };
486 auto lCopy = l;
487 auto lPtrDecay = +[] { };
488 (void)lPtrDecay;
489}
490)cpp";
491
492 EXPECT_TRUE(matches(
493 Code, cxxConstructorDecl(
494 hasBody(compoundStmt()),
495 hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))),
496 isCopyConstructor())));
497 EXPECT_TRUE(matches(
498 Code, cxxConstructorDecl(
499 hasBody(compoundStmt()),
500 hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))),
501 isMoveConstructor())));
502 EXPECT_TRUE(matches(
503 Code, cxxDestructorDecl(
504 hasBody(compoundStmt()),
505 hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))))));
506 EXPECT_TRUE(matches(
507 Code, cxxConversionDecl(hasBody(compoundStmt(has(returnStmt(
508 hasReturnValue(implicitCastExpr()))))),
509 hasAncestor(lambdaExpr(hasAncestor(
510 varDecl(hasName("lPtrDecay"))))))));
511}
512
513TEST(Matcher, isClassMessage) {
514 EXPECT_TRUE(matchesObjC(
515 "@interface NSString +(NSString *) stringWithFormat; @end "
516 "void f() { [NSString stringWithFormat]; }",
517 objcMessageExpr(isClassMessage())));
518
519 EXPECT_FALSE(matchesObjC(
520 "@interface NSString @end "
521 "void f(NSString *x) {"
522 "[x containsString];"
523 "}",
524 objcMessageExpr(isClassMessage())));
525}
526
527TEST(Matcher, isInstanceMessage) {
528 EXPECT_TRUE(matchesObjC(
529 "@interface NSString @end "
530 "void f(NSString *x) {"
531 "[x containsString];"
532 "}",
533 objcMessageExpr(isInstanceMessage())));
534
535 EXPECT_FALSE(matchesObjC(
536 "@interface NSString +(NSString *) stringWithFormat; @end "
537 "void f() { [NSString stringWithFormat]; }",
538 objcMessageExpr(isInstanceMessage())));
539
540}
541
542TEST(Matcher, isClassMethod) {
543 EXPECT_TRUE(matchesObjC(
544 "@interface Bar + (void)bar; @end",
545 objcMethodDecl(isClassMethod())));
546
547 EXPECT_TRUE(matchesObjC(
548 "@interface Bar @end"
549 "@implementation Bar + (void)bar {} @end",
550 objcMethodDecl(isClassMethod())));
551
552 EXPECT_FALSE(matchesObjC(
553 "@interface Foo - (void)foo; @end",
554 objcMethodDecl(isClassMethod())));
555
556 EXPECT_FALSE(matchesObjC(
557 "@interface Foo @end "
558 "@implementation Foo - (void)foo {} @end",
559 objcMethodDecl(isClassMethod())));
560}
561
562TEST(Matcher, isInstanceMethod) {
563 EXPECT_TRUE(matchesObjC(
564 "@interface Foo - (void)foo; @end",
565 objcMethodDecl(isInstanceMethod())));
566
567 EXPECT_TRUE(matchesObjC(
568 "@interface Foo @end "
569 "@implementation Foo - (void)foo {} @end",
570 objcMethodDecl(isInstanceMethod())));
571
572 EXPECT_FALSE(matchesObjC(
573 "@interface Bar + (void)bar; @end",
574 objcMethodDecl(isInstanceMethod())));
575
576 EXPECT_FALSE(matchesObjC(
577 "@interface Bar @end"
578 "@implementation Bar + (void)bar {} @end",
579 objcMethodDecl(isInstanceMethod())));
580}
581
582TEST(MatcherCXXMemberCallExpr, On) {
583 StringRef Snippet1 = R"cc(
584 struct Y {
585 void m();
586 };
587 void z(Y y) { y.m(); }
588 )cc";
589 StringRef Snippet2 = R"cc(
590 struct Y {
591 void m();
592 };
593 struct X : public Y {};
594 void z(X x) { x.m(); }
595 )cc";
596 auto MatchesY = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")))));
597 EXPECT_TRUE(matches(Snippet1, MatchesY));
598 EXPECT_TRUE(notMatches(Snippet2, MatchesY));
599
600 auto MatchesX = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X")))));
601 EXPECT_TRUE(matches(Snippet2, MatchesX));
602
603 // Parens are ignored.
604 StringRef Snippet3 = R"cc(
605 struct Y {
606 void m();
607 };
608 Y g();
609 void z(Y y) { (g()).m(); }
610 )cc";
611 auto MatchesCall = cxxMemberCallExpr(on(callExpr()));
612 EXPECT_TRUE(matches(Snippet3, MatchesCall));
613}
614
615TEST(MatcherCXXMemberCallExpr, OnImplicitObjectArgument) {
616 StringRef Snippet1 = R"cc(
617 struct Y {
618 void m();
619 };
620 void z(Y y) { y.m(); }
621 )cc";
622 StringRef Snippet2 = R"cc(
623 struct Y {
624 void m();
625 };
626 struct X : public Y {};
627 void z(X x) { x.m(); }
628 )cc";
629 auto MatchesY = traverse(TK_AsIs, cxxMemberCallExpr(onImplicitObjectArgument(
630 hasType(cxxRecordDecl(hasName("Y"))))));
631 EXPECT_TRUE(matches(Snippet1, MatchesY));
632 EXPECT_TRUE(matches(Snippet2, MatchesY));
633
634 auto MatchesX = traverse(TK_AsIs, cxxMemberCallExpr(onImplicitObjectArgument(
635 hasType(cxxRecordDecl(hasName("X"))))));
636 EXPECT_TRUE(notMatches(Snippet2, MatchesX));
637
638 // Parens are not ignored.
639 StringRef Snippet3 = R"cc(
640 struct Y {
641 void m();
642 };
643 Y g();
644 void z(Y y) { (g()).m(); }
645 )cc";
646 auto MatchesCall = traverse(
647 TK_AsIs, cxxMemberCallExpr(onImplicitObjectArgument(callExpr())));
648 EXPECT_TRUE(notMatches(Snippet3, MatchesCall));
649}
650
651TEST(Matcher, HasObjectExpr) {
652 StringRef Snippet1 = R"cc(
653 struct X {
654 int m;
655 int f(X x) { return x.m; }
656 };
657 )cc";
658 StringRef Snippet2 = R"cc(
659 struct X {
660 int m;
661 int f(X x) { return m; }
662 };
663 )cc";
664 auto MatchesX =
665 memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))));
666 EXPECT_TRUE(matches(Snippet1, MatchesX));
667 EXPECT_TRUE(notMatches(Snippet2, MatchesX));
668
669 auto MatchesXPointer = memberExpr(
670 hasObjectExpression(hasType(pointsTo(cxxRecordDecl(hasName("X"))))));
671 EXPECT_TRUE(notMatches(Snippet1, MatchesXPointer));
672 EXPECT_TRUE(matches(Snippet2, MatchesXPointer));
673}
674
675TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) {
676 StatementMatcher ArgumentY =
677 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
678 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
679 StatementMatcher CallExpr =
680 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
681
682 // IntParam does not match.
683 EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr));
684 // ArgumentY does not match.
685 EXPECT_TRUE(notMatches("void f(int i) { int x; f(x); }", CallExpr));
686}
687
688TEST(ForEachArgumentWithParam, MatchesCXXMemberCallExpr) {
689 StatementMatcher ArgumentY =
690 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
691 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
692 StatementMatcher CallExpr =
693 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
694 EXPECT_TRUE(matchAndVerifyResultTrue(
695 "struct S {"
696 " const S& operator[](int i) { return *this; }"
697 "};"
698 "void f(S S1) {"
699 " int y = 1;"
700 " S1[y];"
701 "}",
702 CallExpr, std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", 1)));
703
704 StatementMatcher CallExpr2 =
705 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
706 EXPECT_TRUE(matchAndVerifyResultTrue(
707 "struct S {"
708 " static void g(int i);"
709 "};"
710 "void f() {"
711 " int y = 1;"
712 " S::g(y);"
713 "}",
714 CallExpr2, std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", 1)));
715}
716
717TEST(ForEachArgumentWithParam, MatchesCallExpr) {
718 StatementMatcher ArgumentY =
719 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
720 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
721 StatementMatcher CallExpr =
722 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
723
724 EXPECT_TRUE(
725 matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
726 std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>(
727 "param")));
728 EXPECT_TRUE(
729 matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
730 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>(
731 "arg")));
732
733 EXPECT_TRUE(matchAndVerifyResultTrue(
734 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
735 std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", 2)));
736 EXPECT_TRUE(matchAndVerifyResultTrue(
737 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
738 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg", 2)));
739}
740
741TEST(ForEachArgumentWithParam, MatchesConstructExpr) {
742 StatementMatcher ArgumentY =
743 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
744 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
745 StatementMatcher ConstructExpr = traverse(
746 TK_AsIs, cxxConstructExpr(forEachArgumentWithParam(ArgumentY, IntParam)));
747
748 EXPECT_TRUE(matchAndVerifyResultTrue(
749 "struct C {"
750 " C(int i) {}"
751 "};"
752 "int y = 0;"
753 "C Obj(y);",
754 ConstructExpr,
755 std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param")));
756}
757
758TEST(ForEachArgumentWithParam, HandlesBoundNodesForNonMatches) {
759 EXPECT_TRUE(matchAndVerifyResultTrue(
760 "void g(int i, int j) {"
761 " int a;"
762 " int b;"
763 " int c;"
764 " g(a, 0);"
765 " g(a, b);"
766 " g(0, b);"
767 "}",
768 functionDecl(
769 forEachDescendant(varDecl().bind("v")),
770 forEachDescendant(callExpr(forEachArgumentWithParam(
771 declRefExpr(to(decl(equalsBoundNode("v")))), parmVarDecl())))),
772 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("v", 4)));
773}
774
775TEST(ForEachArgumentWithParamType, ReportsNoFalsePositives) {
776 StatementMatcher ArgumentY =
777 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
778 TypeMatcher IntType = qualType(isInteger()).bind("type");
779 StatementMatcher CallExpr =
780 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
781
782 // IntParam does not match.
783 EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr));
784 // ArgumentY does not match.
785 EXPECT_TRUE(notMatches("void f(int i) { int x; f(x); }", CallExpr));
786}
787
788TEST(ForEachArgumentWithParamType, MatchesCXXMemberCallExpr) {
789 StatementMatcher ArgumentY =
790 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
791 TypeMatcher IntType = qualType(isInteger()).bind("type");
792 StatementMatcher CallExpr =
793 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
794 EXPECT_TRUE(matchAndVerifyResultTrue(
795 "struct S {"
796 " const S& operator[](int i) { return *this; }"
797 "};"
798 "void f(S S1) {"
799 " int y = 1;"
800 " S1[y];"
801 "}",
802 CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 1)));
803
804 StatementMatcher CallExpr2 =
805 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
806 EXPECT_TRUE(matchAndVerifyResultTrue(
807 "struct S {"
808 " static void g(int i);"
809 "};"
810 "void f() {"
811 " int y = 1;"
812 " S::g(y);"
813 "}",
814 CallExpr2, std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 1)));
815}
816
817TEST(ForEachArgumentWithParamType, MatchesCallExpr) {
818 StatementMatcher ArgumentY =
819 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
820 TypeMatcher IntType = qualType(isInteger()).bind("type");
821 StatementMatcher CallExpr =
822 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
823
824 EXPECT_TRUE(matchAndVerifyResultTrue(
825 "void f(int i) { int y; f(y); }", CallExpr,
826 std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
827 EXPECT_TRUE(matchAndVerifyResultTrue(
828 "void f(int i) { int y; f(y); }", CallExpr,
829 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
830
831 EXPECT_TRUE(matchAndVerifyResultTrue(
832 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
833 std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 2)));
834 EXPECT_TRUE(matchAndVerifyResultTrue(
835 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
836 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg", 2)));
837}
838
839TEST(ForEachArgumentWithParamType, MatchesConstructExpr) {
840 StatementMatcher ArgumentY =
841 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
842 TypeMatcher IntType = qualType(isInteger()).bind("type");
843 StatementMatcher ConstructExpr =
844 cxxConstructExpr(forEachArgumentWithParamType(ArgumentY, IntType));
845
846 EXPECT_TRUE(matchAndVerifyResultTrue(
847 "struct C {"
848 " C(int i) {}"
849 "};"
850 "int y = 0;"
851 "C Obj(y);",
852 ConstructExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
853 EXPECT_TRUE(matchAndVerifyResultTrue(
854 "struct C {"
855 " C(int i) {}"
856 "};"
857 "int y = 0;"
858 "C Obj(y);",
859 ConstructExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
860}
861
862TEST(ForEachArgumentWithParamType, HandlesKandRFunctions) {
863 StatementMatcher ArgumentY =
864 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
865 TypeMatcher IntType = qualType(isInteger()).bind("type");
866 StatementMatcher CallExpr =
867 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
868
869 EXPECT_TRUE(matchesC("void f();\n"
870 "void call_it(void) { int x, y; f(x, y); }\n"
871 "void f(a, b) int a, b; {}\n"
872 "void call_it2(void) { int x, y; f(x, y); }",
873 CallExpr));
874}
875
876TEST(ForEachArgumentWithParamType, HandlesBoundNodesForNonMatches) {
877 EXPECT_TRUE(matchAndVerifyResultTrue(
878 "void g(int i, int j) {"
879 " int a;"
880 " int b;"
881 " int c;"
882 " g(a, 0);"
883 " g(a, b);"
884 " g(0, b);"
885 "}",
886 functionDecl(
887 forEachDescendant(varDecl().bind("v")),
888 forEachDescendant(callExpr(forEachArgumentWithParamType(
889 declRefExpr(to(decl(equalsBoundNode("v")))), qualType())))),
890 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("v", 4)));
891}
892
893TEST(ForEachArgumentWithParamType, MatchesFunctionPtrCalls) {
894 StatementMatcher ArgumentY =
895 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
896 TypeMatcher IntType = qualType(builtinType()).bind("type");
897 StatementMatcher CallExpr =
898 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
899
900 EXPECT_TRUE(matchAndVerifyResultTrue(
901 "void f(int i) {"
902 "void (*f_ptr)(int) = f; int y; f_ptr(y); }",
903 CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
904 EXPECT_TRUE(matchAndVerifyResultTrue(
905 "void f(int i) {"
906 "void (*f_ptr)(int) = f; int y; f_ptr(y); }",
907 CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
908}
909
910TEST(ForEachArgumentWithParamType, MatchesMemberFunctionPtrCalls) {
911 StatementMatcher ArgumentY =
912 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
913 TypeMatcher IntType = qualType(builtinType()).bind("type");
914 StatementMatcher CallExpr =
915 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
916
917 StringRef S = "struct A {\n"
918 " int f(int i) { return i + 1; }\n"
919 " int (A::*x)(int);\n"
920 "};\n"
921 "void f() {\n"
922 " int y = 42;\n"
923 " A a;\n"
924 " a.x = &A::f;\n"
925 " (a.*(a.x))(y);\n"
926 "}";
927 EXPECT_TRUE(matchAndVerifyResultTrue(
928 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
929 EXPECT_TRUE(matchAndVerifyResultTrue(
930 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
931}
932
933TEST(QualType, hasCanonicalType) {
934 EXPECT_TRUE(notMatches("typedef int &int_ref;"
935 "int a;"
936 "int_ref b = a;",
937 varDecl(hasType(qualType(referenceType())))));
938 EXPECT_TRUE(
939 matches("typedef int &int_ref;"
940 "int a;"
941 "int_ref b = a;",
942 varDecl(hasType(qualType(hasCanonicalType(referenceType()))))));
943}
944
945TEST(HasParameter, CallsInnerMatcher) {
946 EXPECT_TRUE(matches("class X { void x(int) {} };",
947 cxxMethodDecl(hasParameter(0, varDecl()))));
948 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
949 cxxMethodDecl(hasParameter(0, hasName("x")))));
950 EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end",
951 objcMethodDecl(hasParameter(0, hasName("x")))));
952 EXPECT_TRUE(matchesObjC("int main() { void (^b)(int) = ^(int p) {}; }",
953 blockDecl(hasParameter(0, hasName("p")))));
954}
955
956TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
957 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
958 cxxMethodDecl(hasParameter(42, varDecl()))));
959}
960
961TEST(HasType, MatchesParameterVariableTypesStrictly) {
962 EXPECT_TRUE(matches(
963 "class X { void x(X x) {} };",
964 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
965 EXPECT_TRUE(notMatches(
966 "class X { void x(const X &x) {} };",
967 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
968 EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
969 cxxMethodDecl(hasParameter(
970 0, hasType(pointsTo(recordDecl(hasName("X"))))))));
971 EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
972 cxxMethodDecl(hasParameter(
973 0, hasType(references(recordDecl(hasName("X"))))))));
974}
975
976TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
977 EXPECT_TRUE(matches(
978 "class Y {}; class X { void x(X x, Y y) {} };",
979 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
980 EXPECT_TRUE(matches(
981 "class Y {}; class X { void x(Y y, X x) {} };",
982 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
983 EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end",
984 objcMethodDecl(hasAnyParameter(hasName("x")))));
985 EXPECT_TRUE(matchesObjC("int main() { void (^b)(int) = ^(int p) {}; }",
986 blockDecl(hasAnyParameter(hasName("p")))));
987}
988
989TEST(Returns, MatchesReturnTypes) {
990 EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
991 functionDecl(returns(asString("int")))));
992 EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
993 functionDecl(returns(asString("float")))));
994 EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
995 functionDecl(returns(hasDeclaration(
996 recordDecl(hasName("Y")))))));
997}
998
999TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
1000 EXPECT_TRUE(notMatches(
1001 "class Y {}; class X { void x(int) {} };",
1002 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1003}
1004
1005TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1006 EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
1007 cxxMethodDecl(hasAnyParameter(
1008 hasType(pointsTo(recordDecl(hasName("X"))))))));
1009}
1010
1011TEST(HasName, MatchesParameterVariableDeclarations) {
1012 EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
1013 cxxMethodDecl(hasAnyParameter(hasName("x")))));
1014 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1015 cxxMethodDecl(hasAnyParameter(hasName("x")))));
1016}
1017
1018TEST(Matcher, MatchesTypeTemplateArgument) {
1019 EXPECT_TRUE(matches(
1020 "template<typename T> struct B {};"
1021 "B<int> b;",
1022 classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
1023 asString("int"))))));
1024}
1025
1026TEST(Matcher, MatchesTemplateTemplateArgument) {
1027 EXPECT_TRUE(matches("template<template <typename> class S> class X {};"
1028 "template<typename T> class Y {};"
1029 "X<Y> xi;",
1030 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1031 refersToTemplate(templateName())))));
1032}
1033
1034TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1035 EXPECT_TRUE(matches(
1036 "struct B { int next; };"
1037 "template<int(B::*next_ptr)> struct A {};"
1038 "A<&B::next> a;",
1039 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1040 refersToDeclaration(fieldDecl(hasName("next")))))));
1041
1042 EXPECT_TRUE(notMatches(
1043 "template <typename T> struct A {};"
1044 "A<int> a;",
1045 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1046 refersToDeclaration(decl())))));
1047
1048 EXPECT_TRUE(matches(
1049 "struct B { int next; };"
1050 "template<int(B::*next_ptr)> struct A {};"
1051 "A<&B::next> a;",
1052 templateSpecializationType(hasAnyTemplateArgument(isExpr(
1053 hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))));
1054
1055 EXPECT_TRUE(notMatches(
1056 "template <typename T> struct A {};"
1057 "A<int> a;",
1058 templateSpecializationType(hasAnyTemplateArgument(
1059 refersToDeclaration(decl())))));
1060}
1061
1062
1063TEST(Matcher, MatchesSpecificArgument) {
1064 EXPECT_TRUE(matches(
1065 "template<typename T, typename U> class A {};"
1066 "A<bool, int> a;",
1067 classTemplateSpecializationDecl(hasTemplateArgument(
1068 1, refersToType(asString("int"))))));
1069 EXPECT_TRUE(notMatches(
1070 "template<typename T, typename U> class A {};"
1071 "A<int, bool> a;",
1072 classTemplateSpecializationDecl(hasTemplateArgument(
1073 1, refersToType(asString("int"))))));
1074
1075 EXPECT_TRUE(matches(
1076 "template<typename T, typename U> class A {};"
1077 "A<bool, int> a;",
1078 templateSpecializationType(hasTemplateArgument(
1079 1, refersToType(asString("int"))))));
1080 EXPECT_TRUE(notMatches(
1081 "template<typename T, typename U> class A {};"
1082 "A<int, bool> a;",
1083 templateSpecializationType(hasTemplateArgument(
1084 1, refersToType(asString("int"))))));
1085
1086 EXPECT_TRUE(matches(
1087 "template<typename T> void f() {};"
1088 "void func() { f<int>(); }",
1089 functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))));
1090 EXPECT_TRUE(notMatches(
1091 "template<typename T> void f() {};",
1092 functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))));
1093}
1094
1095TEST(TemplateArgument, Matches) {
1096 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
1097 classTemplateSpecializationDecl(
1098 hasAnyTemplateArgument(templateArgument()))));
1099 EXPECT_TRUE(matches(
1100 "template<typename T> struct C {}; C<int> c;",
1101 templateSpecializationType(hasAnyTemplateArgument(templateArgument()))));
1102
1103 EXPECT_TRUE(matches(
1104 "template<typename T> void f() {};"
1105 "void func() { f<int>(); }",
1106 functionDecl(hasAnyTemplateArgument(templateArgument()))));
1107}
1108
1109TEST(TemplateTypeParmDecl, CXXMethodDecl) {
1110 const char input[] =
1111 "template<typename T>\n"
1112 "class Class {\n"
1113 " void method();\n"
1114 "};\n"
1115 "template<typename U>\n"
1116 "void Class<U>::method() {}\n";
1117 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1118 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1119}
1120
1121TEST(TemplateTypeParmDecl, VarDecl) {
1122 const char input[] =
1123 "template<typename T>\n"
1124 "class Class {\n"
1125 " static T pi;\n"
1126 "};\n"
1127 "template<typename U>\n"
1128 "U Class<U>::pi = U(3.1415926535897932385);\n";
1129 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1130 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1131}
1132
1133TEST(TemplateTypeParmDecl, VarTemplatePartialSpecializationDecl) {
1134 const char input[] =
1135 "template<typename T>\n"
1136 "struct Struct {\n"
1137 " template<typename T2> static int field;\n"
1138 "};\n"
1139 "template<typename U>\n"
1140 "template<typename U2>\n"
1141 "int Struct<U>::field<U2*> = 123;\n";
1142 EXPECT_TRUE(
1143 matches(input, templateTypeParmDecl(hasName("T")), langCxx14OrLater()));
1144 EXPECT_TRUE(
1145 matches(input, templateTypeParmDecl(hasName("T2")), langCxx14OrLater()));
1146 EXPECT_TRUE(
1147 matches(input, templateTypeParmDecl(hasName("U")), langCxx14OrLater()));
1148 EXPECT_TRUE(
1149 matches(input, templateTypeParmDecl(hasName("U2")), langCxx14OrLater()));
1150}
1151
1152TEST(TemplateTypeParmDecl, ClassTemplatePartialSpecializationDecl) {
1153 const char input[] =
1154 "template<typename T>\n"
1155 "class Class {\n"
1156 " template<typename T2> struct Struct;\n"
1157 "};\n"
1158 "template<typename U>\n"
1159 "template<typename U2>\n"
1160 "struct Class<U>::Struct<U2*> {};\n";
1161 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1162 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T2"))));
1163 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1164 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U2"))));
1165}
1166
1167TEST(TemplateTypeParmDecl, EnumDecl) {
1168 const char input[] =
1169 "template<typename T>\n"
1170 "struct Struct {\n"
1171 " enum class Enum : T;\n"
1172 "};\n"
1173 "template<typename U>\n"
1174 "enum class Struct<U>::Enum : U {\n"
1175 " e1,\n"
1176 " e2\n"
1177 "};\n";
1178 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1179 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1180}
1181
1182TEST(TemplateTypeParmDecl, RecordDecl) {
1183 const char input[] =
1184 "template<typename T>\n"
1185 "class Class {\n"
1186 " struct Struct;\n"
1187 "};\n"
1188 "template<typename U>\n"
1189 "struct Class<U>::Struct {\n"
1190 " U field;\n"
1191 "};\n";
1192 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1193 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1194}
1195
1196TEST(RefersToIntegralType, Matches) {
1197 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
1198 classTemplateSpecializationDecl(
1199 hasAnyTemplateArgument(refersToIntegralType(
1200 asString("int"))))));
1201 EXPECT_TRUE(notMatches("template<unsigned T> struct C {}; C<42> c;",
1202 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1203 refersToIntegralType(asString("int"))))));
1204}
1205
1206TEST(ConstructorDeclaration, SimpleCase) {
1207 EXPECT_TRUE(matches("class Foo { Foo(int i); };",
1208 cxxConstructorDecl(ofClass(hasName("Foo")))));
1209 EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
1210 cxxConstructorDecl(ofClass(hasName("Bar")))));
1211}
1212
1213TEST(DestructorDeclaration, MatchesVirtualDestructor) {
1214 EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
1215 cxxDestructorDecl(ofClass(hasName("Foo")))));
1216}
1217
1218TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
1219 EXPECT_TRUE(notMatches("class Foo {};",
1220 cxxDestructorDecl(ofClass(hasName("Foo")))));
1221}
1222
1223TEST(HasAnyConstructorInitializer, SimpleCase) {
1224 EXPECT_TRUE(
1225 notMatches("class Foo { Foo() { } };",
1226 cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
1227 EXPECT_TRUE(
1228 matches("class Foo {"
1229 " Foo() : foo_() { }"
1230 " int foo_;"
1231 "};",
1232 cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
1233}
1234
1235TEST(HasAnyConstructorInitializer, ForField) {
1236 static const char Code[] =
1237 "class Baz { };"
1238 "class Foo {"
1239 " Foo() : foo_(), bar_() { }"
1240 " Baz foo_;"
1241 " struct {"
1242 " Baz bar_;"
1243 " };"
1244 "};";
1245 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1246 forField(hasType(recordDecl(hasName("Baz"))))))));
1247 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1248 forField(hasName("foo_"))))));
1249 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1250 forField(hasName("bar_"))))));
1251 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1252 forField(hasType(recordDecl(hasName("Bar"))))))));
1253}
1254
1255TEST(HasAnyConstructorInitializer, WithInitializer) {
1256 static const char Code[] =
1257 "class Foo {"
1258 " Foo() : foo_(0) { }"
1259 " int foo_;"
1260 "};";
1261 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1262 withInitializer(integerLiteral(equals(0)))))));
1263 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1264 withInitializer(integerLiteral(equals(1)))))));
1265}
1266
1267TEST(HasAnyConstructorInitializer, IsWritten) {
1268 static const char Code[] =
1269 "struct Bar { Bar(){} };"
1270 "class Foo {"
1271 " Foo() : foo_() { }"
1272 " Bar foo_;"
1273 " Bar bar_;"
1274 "};";
1275 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1276 allOf(forField(hasName("foo_")), isWritten())))));
1277 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1278 allOf(forField(hasName("bar_")), isWritten())))));
1279 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1280 allOf(forField(hasName("bar_")), unless(isWritten()))))));
1281}
1282
1283TEST(HasAnyConstructorInitializer, IsBaseInitializer) {
1284 static const char Code[] =
1285 "struct B {};"
1286 "struct D : B {"
1287 " int I;"
1288 " D(int i) : I(i) {}"
1289 "};"
1290 "struct E : B {"
1291 " E() : B() {}"
1292 "};";
1293 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
1294 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
1295 hasName("E")))));
1296 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
1297 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
1298 hasName("D")))));
1299 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
1300 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
1301 hasName("D")))));
1302 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
1303 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
1304 hasName("E")))));
1305}
1306
1307TEST(IfStmt, ChildTraversalMatchers) {
1308 EXPECT_TRUE(matches("void f() { if (false) true; else false; }",
1309 ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
1310 EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }",
1311 ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
1312 EXPECT_TRUE(matches("void f() { if (false) false; else true; }",
1313 ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
1314 EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }",
1315 ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
1316}
1317
1318TEST(MatchBinaryOperator, HasOperatorName) {
1319 StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
1320
1321 EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
1322 EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
1323}
1324
1325TEST(MatchBinaryOperator, HasAnyOperatorName) {
1326 StatementMatcher Matcher =
1327 binaryOperator(hasAnyOperatorName("+", "-", "*", "/"));
1328
1329 EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher));
1330 EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher));
1331 EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher));
1332 EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher));
1333 EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher));
1334 // Ensure '+= isn't mistaken.
1335 EXPECT_TRUE(notMatches("void x(int &I) { I += 1; }", Matcher));
1336}
1337
1338TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
1339 StatementMatcher OperatorTrueFalse =
1340 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
1341 hasRHS(cxxBoolLiteral(equals(false))));
1342
1343 EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
1344 EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
1345 EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
1346
1347 StatementMatcher OperatorIntPointer = arraySubscriptExpr(
1348 hasLHS(hasType(isInteger())),
1349 traverse(TK_AsIs, hasRHS(hasType(pointsTo(qualType())))));
1350 EXPECT_TRUE(matches("void x() { 1[\"abc\"]; }", OperatorIntPointer));
1351 EXPECT_TRUE(notMatches("void x() { \"abc\"[1]; }", OperatorIntPointer));
1352
1353 StringRef Code = R"cpp(
1354struct HasOpEqMem
1355{
1356 bool operator==(const HasOpEqMem& other) const
1357 {
1358 return true;
1359 }
1360};
1361
1362struct HasOpFree
1363{
1364};
1365bool operator==(const HasOpFree& lhs, const HasOpFree& rhs)
1366{
1367 return true;
1368}
1369
1370void opMem()
1371{
1372 HasOpEqMem s1;
1373 HasOpEqMem s2;
1374 if (s1 == s2)
1375 return;
1376}
1377
1378void opFree()
1379{
1380 HasOpFree s1;
1381 HasOpFree s2;
1382 if (s1 == s2)
1383 return;
1384}
1385)cpp";
1386 auto s1Expr = declRefExpr(to(varDecl(hasName("s1"))));
1387 auto s2Expr = declRefExpr(to(varDecl(hasName("s2"))));
1388 EXPECT_TRUE(matches(
1389 Code,
1390 traverse(TK_IgnoreUnlessSpelledInSource,
1391 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opMem"))),
1392 hasOperatorName("=="), hasLHS(s1Expr),
1393 hasRHS(s2Expr)))));
1394 EXPECT_TRUE(matches(
1395 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1396 cxxOperatorCallExpr(
1397 forFunction(functionDecl(hasName("opMem"))),
1398 hasAnyOperatorName("!=", "=="), hasLHS(s1Expr)))));
1399 EXPECT_TRUE(matches(
1400 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1401 cxxOperatorCallExpr(
1402 forFunction(functionDecl(hasName("opMem"))),
1403 hasOperatorName("=="), hasOperands(s1Expr, s2Expr)))));
1404 EXPECT_TRUE(matches(
1405 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1406 cxxOperatorCallExpr(
1407 forFunction(functionDecl(hasName("opMem"))),
1408 hasOperatorName("=="), hasEitherOperand(s2Expr)))));
1409
1410 EXPECT_TRUE(matches(
1411 Code,
1412 traverse(TK_IgnoreUnlessSpelledInSource,
1413 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opFree"))),
1414 hasOperatorName("=="), hasLHS(s1Expr),
1415 hasRHS(s2Expr)))));
1416 EXPECT_TRUE(matches(
1417 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1418 cxxOperatorCallExpr(
1419 forFunction(functionDecl(hasName("opFree"))),
1420 hasAnyOperatorName("!=", "=="), hasLHS(s1Expr)))));
1421 EXPECT_TRUE(matches(
1422 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1423 cxxOperatorCallExpr(
1424 forFunction(functionDecl(hasName("opFree"))),
1425 hasOperatorName("=="), hasOperands(s1Expr, s2Expr)))));
1426 EXPECT_TRUE(matches(
1427 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1428 cxxOperatorCallExpr(
1429 forFunction(functionDecl(hasName("opFree"))),
1430 hasOperatorName("=="), hasEitherOperand(s2Expr)))));
1431}
1432
1433TEST(MatchBinaryOperator, HasEitherOperand) {
1434 StatementMatcher HasOperand =
1435 binaryOperator(hasEitherOperand(cxxBoolLiteral(equals(false))));
1436
1437 EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
1438 EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
1439 EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
1440}
1441
1442TEST(MatchBinaryOperator, HasOperands) {
1443 StatementMatcher HasOperands = binaryOperator(
1444 hasOperands(integerLiteral(equals(1)), integerLiteral(equals(2))));
1445 EXPECT_TRUE(matches("void x() { 1 + 2; }", HasOperands));
1446 EXPECT_TRUE(matches("void x() { 2 + 1; }", HasOperands));
1447 EXPECT_TRUE(notMatches("void x() { 1 + 1; }", HasOperands));
1448 EXPECT_TRUE(notMatches("void x() { 2 + 2; }", HasOperands));
1449 EXPECT_TRUE(notMatches("void x() { 0 + 0; }", HasOperands));
1450 EXPECT_TRUE(notMatches("void x() { 0 + 1; }", HasOperands));
1451}
1452
1453TEST(Matcher, BinaryOperatorTypes) {
1454 // Integration test that verifies the AST provides all binary operators in
1455 // a way we expect.
1456 // FIXME: Operator ','
1457 EXPECT_TRUE(
1458 matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
1459 EXPECT_TRUE(
1460 matches("bool b; bool c = (b = true);",
1461 binaryOperator(hasOperatorName("="))));
1462 EXPECT_TRUE(
1463 matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
1464 EXPECT_TRUE(
1465 matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
1466 EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
1467 EXPECT_TRUE(
1468 matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
1469 EXPECT_TRUE(
1470 matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
1471 EXPECT_TRUE(
1472 matches("int i = 1; int j = (i <<= 2);",
1473 binaryOperator(hasOperatorName("<<="))));
1474 EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
1475 EXPECT_TRUE(
1476 matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
1477 EXPECT_TRUE(
1478 matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
1479 EXPECT_TRUE(
1480 matches("int i = 1; int j = (i >>= 2);",
1481 binaryOperator(hasOperatorName(">>="))));
1482 EXPECT_TRUE(
1483 matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
1484 EXPECT_TRUE(
1485 matches("int i = 42; int j = (i ^= 42);",
1486 binaryOperator(hasOperatorName("^="))));
1487 EXPECT_TRUE(
1488 matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
1489 EXPECT_TRUE(
1490 matches("int i = 42; int j = (i %= 42);",
1491 binaryOperator(hasOperatorName("%="))));
1492 EXPECT_TRUE(
1493 matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&"))));
1494 EXPECT_TRUE(
1495 matches("bool b = true && false;",
1496 binaryOperator(hasOperatorName("&&"))));
1497 EXPECT_TRUE(
1498 matches("bool b = true; bool c = (b &= false);",
1499 binaryOperator(hasOperatorName("&="))));
1500 EXPECT_TRUE(
1501 matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
1502 EXPECT_TRUE(
1503 matches("bool b = true || false;",
1504 binaryOperator(hasOperatorName("||"))));
1505 EXPECT_TRUE(
1506 matches("bool b = true; bool c = (b |= false);",
1507 binaryOperator(hasOperatorName("|="))));
1508 EXPECT_TRUE(
1509 matches("int i = 42 *23;", binaryOperator(hasOperatorName("*"))));
1510 EXPECT_TRUE(
1511 matches("int i = 42; int j = (i *= 23);",
1512 binaryOperator(hasOperatorName("*="))));
1513 EXPECT_TRUE(
1514 matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
1515 EXPECT_TRUE(
1516 matches("int i = 42; int j = (i /= 23);",
1517 binaryOperator(hasOperatorName("/="))));
1518 EXPECT_TRUE(
1519 matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
1520 EXPECT_TRUE(
1521 matches("int i = 42; int j = (i += 23);",
1522 binaryOperator(hasOperatorName("+="))));
1523 EXPECT_TRUE(
1524 matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
1525 EXPECT_TRUE(
1526 matches("int i = 42; int j = (i -= 23);",
1527 binaryOperator(hasOperatorName("-="))));
1528 EXPECT_TRUE(
1529 matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
1530 binaryOperator(hasOperatorName("->*"))));
1531 EXPECT_TRUE(
1532 matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
1533 binaryOperator(hasOperatorName(".*"))));
1534
1535 // Member expressions as operators are not supported in matches.
1536 EXPECT_TRUE(
1537 notMatches("struct A { void x(A *a) { a->x(this); } };",
1538 binaryOperator(hasOperatorName("->"))));
1539
1540 // Initializer assignments are not represented as operator equals.
1541 EXPECT_TRUE(
1542 notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
1543
1544 // Array indexing is not represented as operator.
1545 EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
1546
1547 // Overloaded operators do not match at all.
1548 EXPECT_TRUE(notMatches(
1549 "struct A { bool operator&&(const A &a) const { return false; } };"
1550 "void x() { A a, b; a && b; }",
1551 binaryOperator()));
1552}
1553
1554TEST(MatchUnaryOperator, HasOperatorName) {
1555 StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
1556
1557 EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
1558 EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
1559}
1560
1561TEST(MatchUnaryOperator, HasAnyOperatorName) {
1562 StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++"));
1563
1564 EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher));
1565 EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher));
1566 EXPECT_TRUE(matches("void x(int &I) { I++; }", Matcher));
1567 EXPECT_TRUE(matches("void x(int &I) { ++I; }", Matcher));
1568 EXPECT_TRUE(notMatches("void x(int &I) { I--; }", Matcher));
1569 EXPECT_TRUE(notMatches("void x(int &I) { --I; }", Matcher));
1570 EXPECT_TRUE(notMatches("int *x(int &I) { return &I; }", Matcher));
1571}
1572
1573TEST(MatchUnaryOperator, HasUnaryOperand) {
1574 StatementMatcher OperatorOnFalse =
1575 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false))));
1576
1577 EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
1578 EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
1579
1580 StringRef Code = R"cpp(
1581struct HasOpBangMem
1582{
1583 bool operator!() const
1584 {
1585 return false;
1586 }
1587};
1588struct HasOpBangFree
1589{
1590};
1591bool operator!(HasOpBangFree const&)
1592{
1593 return false;
1594}
1595
1596void opMem()
1597{
1598 HasOpBangMem s1;
1599 if (!s1)
1600 return;
1601}
1602void opFree()
1603{
1604 HasOpBangFree s1;
1605 if (!s1)
1606 return;
1607}
1608)cpp";
1609 auto s1Expr = declRefExpr(to(varDecl(hasName("s1"))));
1610 EXPECT_TRUE(matches(
1611 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1612 cxxOperatorCallExpr(
1613 forFunction(functionDecl(hasName("opMem"))),
1614 hasOperatorName("!"), hasUnaryOperand(s1Expr)))));
1615 EXPECT_TRUE(matches(
1616 Code,
1617 traverse(TK_IgnoreUnlessSpelledInSource,
1618 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opMem"))),
1619 hasAnyOperatorName("+", "!"),
1620 hasUnaryOperand(s1Expr)))));
1621
1622 EXPECT_TRUE(matches(
1623 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1624 cxxOperatorCallExpr(
1625 forFunction(functionDecl(hasName("opFree"))),
1626 hasOperatorName("!"), hasUnaryOperand(s1Expr)))));
1627 EXPECT_TRUE(matches(
1628 Code,
1629 traverse(TK_IgnoreUnlessSpelledInSource,
1630 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opFree"))),
1631 hasAnyOperatorName("+", "!"),
1632 hasUnaryOperand(s1Expr)))));
1633}
1634
1635TEST(Matcher, UnaryOperatorTypes) {
1636 // Integration test that verifies the AST provides all unary operators in
1637 // a way we expect.
1638 EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
1639 EXPECT_TRUE(
1640 matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
1641 EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
1642 EXPECT_TRUE(
1643 matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
1644 EXPECT_TRUE(
1645 matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
1646 EXPECT_TRUE(
1647 matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
1648 EXPECT_TRUE(
1649 matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
1650 EXPECT_TRUE(
1651 matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
1652 EXPECT_TRUE(
1653 matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
1654 EXPECT_TRUE(
1655 matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
1656
1657 // We don't match conversion operators.
1658 EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
1659
1660 // Function calls are not represented as operator.
1661 EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
1662
1663 // Overloaded operators do not match at all.
1664 // FIXME: We probably want to add that.
1665 EXPECT_TRUE(notMatches(
1666 "struct A { bool operator!() const { return false; } };"
1667 "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
1668}
1669
1670TEST(ArraySubscriptMatchers, ArrayIndex) {
1671 EXPECT_TRUE(matches(
1672 "int i[2]; void f() { i[1] = 1; }",
1673 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1674 EXPECT_TRUE(matches(
1675 "int i[2]; void f() { 1[i] = 1; }",
1676 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1677 EXPECT_TRUE(notMatches(
1678 "int i[2]; void f() { i[1] = 1; }",
1679 arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
1680}
1681
1682TEST(ArraySubscriptMatchers, MatchesArrayBase) {
1683 EXPECT_TRUE(
1684 matches("int i[2]; void f() { i[1] = 2; }",
1685 traverse(TK_AsIs, arraySubscriptExpr(hasBase(implicitCastExpr(
1686 hasSourceExpression(declRefExpr())))))));
1687}
1688
1689TEST(Matcher, OfClass) {
1690 StatementMatcher Constructor = cxxConstructExpr(hasDeclaration(cxxMethodDecl(
1691 ofClass(hasName("X")))));
1692
1693 EXPECT_TRUE(
1694 matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
1695 EXPECT_TRUE(
1696 matches("class X { public: X(); }; void x(int) { X x = X(); }",
1697 Constructor));
1698 EXPECT_TRUE(
1699 notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
1700 Constructor));
1701}
1702
1703TEST(Matcher, VisitsTemplateInstantiations) {
1704 EXPECT_TRUE(matches(
1705 "class A { public: void x(); };"
1706 "template <typename T> class B { public: void y() { T t; t.x(); } };"
1707 "void f() { B<A> b; b.y(); }",
1708 callExpr(callee(cxxMethodDecl(hasName("x"))))));
1709
1710 EXPECT_TRUE(matches(
1711 "class A { public: void x(); };"
1712 "class C {"
1713 " public:"
1714 " template <typename T> class B { public: void y() { T t; t.x(); } };"
1715 "};"
1716 "void f() {"
1717 " C::B<A> b; b.y();"
1718 "}",
1719 recordDecl(hasName("C"), hasDescendant(callExpr(
1720 callee(cxxMethodDecl(hasName("x"))))))));
1721}
1722
1723TEST(Matcher, HasCondition) {
1724 StatementMatcher IfStmt =
1725 ifStmt(hasCondition(cxxBoolLiteral(equals(true))));
1726 EXPECT_TRUE(matches("void x() { if (true) {} }", IfStmt));
1727 EXPECT_TRUE(notMatches("void x() { if (false) {} }", IfStmt));
1728
1729 StatementMatcher ForStmt =
1730 forStmt(hasCondition(cxxBoolLiteral(equals(true))));
1731 EXPECT_TRUE(matches("void x() { for (;true;) {} }", ForStmt));
1732 EXPECT_TRUE(notMatches("void x() { for (;false;) {} }", ForStmt));
1733
1734 StatementMatcher WhileStmt =
1735 whileStmt(hasCondition(cxxBoolLiteral(equals(true))));
1736 EXPECT_TRUE(matches("void x() { while (true) {} }", WhileStmt));
1737 EXPECT_TRUE(notMatches("void x() { while (false) {} }", WhileStmt));
1738
1739 StatementMatcher SwitchStmt =
1740 switchStmt(hasCondition(integerLiteral(equals(42))));
1741 EXPECT_TRUE(matches("void x() { switch (42) {case 42:;} }", SwitchStmt));
1742 EXPECT_TRUE(notMatches("void x() { switch (43) {case 43:;} }", SwitchStmt));
1743}
1744
1745TEST(For, ForLoopInternals) {
1746 EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
1747 forStmt(hasCondition(anything()))));
1748 EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
1749 forStmt(hasLoopInit(anything()))));
1750}
1751
1752TEST(For, ForRangeLoopInternals) {
1753 EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }",
1754 cxxForRangeStmt(hasLoopVariable(anything()))));
1755 EXPECT_TRUE(matches(
1756 "void f(){ int a[] {1, 2}; for (int i : a); }",
1757 cxxForRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))))));
1758}
1759
1760TEST(For, NegativeForLoopInternals) {
1761 EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
1762 forStmt(hasCondition(expr()))));
1763 EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
1764 forStmt(hasLoopInit(anything()))));
1765}
1766
1767TEST(HasBody, FindsBodyOfForWhileDoLoops) {
1768 EXPECT_TRUE(matches("void f() { for(;;) {} }",
1769 forStmt(hasBody(compoundStmt()))));
1770 EXPECT_TRUE(notMatches("void f() { for(;;); }",
1771 forStmt(hasBody(compoundStmt()))));
1772 EXPECT_TRUE(matches("void f() { while(true) {} }",
1773 whileStmt(hasBody(compoundStmt()))));
1774 EXPECT_TRUE(matches("void f() { do {} while(true); }",
1775 doStmt(hasBody(compoundStmt()))));
1776 EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }",
1777 cxxForRangeStmt(hasBody(compoundStmt()))));
1778}
1779
1780TEST(HasBody, FindsBodyOfFunctions) {
1781 EXPECT_TRUE(matches("void f() {}", functionDecl(hasBody(compoundStmt()))));
1782 EXPECT_TRUE(notMatches("void f();", functionDecl(hasBody(compoundStmt()))));
1783 EXPECT_TRUE(matchAndVerifyResultTrue(
1784 "void f(); void f() {}",
1785 functionDecl(hasBody(compoundStmt())).bind("func"),
1786 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("func", 1)));
1787 EXPECT_TRUE(matchAndVerifyResultTrue(
1788 "class C { void f(); }; void C::f() {}",
1789 cxxMethodDecl(hasBody(compoundStmt())).bind("met"),
1790 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("met", 1)));
1791 EXPECT_TRUE(matchAndVerifyResultTrue(
1792 "class C { C(); }; C::C() {}",
1793 cxxConstructorDecl(hasBody(compoundStmt())).bind("ctr"),
1794 std::make_unique<VerifyIdIsBoundTo<CXXConstructorDecl>>("ctr", 1)));
1795 EXPECT_TRUE(matchAndVerifyResultTrue(
1796 "class C { ~C(); }; C::~C() {}",
1797 cxxDestructorDecl(hasBody(compoundStmt())).bind("dtr"),
1798 std::make_unique<VerifyIdIsBoundTo<CXXDestructorDecl>>("dtr", 1)));
1799}
1800
1801TEST(HasAnyBody, FindsAnyBodyOfFunctions) {
1802 EXPECT_TRUE(matches("void f() {}", functionDecl(hasAnyBody(compoundStmt()))));
1803 EXPECT_TRUE(notMatches("void f();",
1804 functionDecl(hasAnyBody(compoundStmt()))));
1805 EXPECT_TRUE(matchAndVerifyResultTrue(
1806 "void f(); void f() {}",
1807 functionDecl(hasAnyBody(compoundStmt())).bind("func"),
1808 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("func", 2)));
1809 EXPECT_TRUE(matchAndVerifyResultTrue(
1810 "class C { void f(); }; void C::f() {}",
1811 cxxMethodDecl(hasAnyBody(compoundStmt())).bind("met"),
1812 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("met", 2)));
1813 EXPECT_TRUE(matchAndVerifyResultTrue(
1814 "class C { C(); }; C::C() {}",
1815 cxxConstructorDecl(hasAnyBody(compoundStmt())).bind("ctr"),
1816 std::make_unique<VerifyIdIsBoundTo<CXXConstructorDecl>>("ctr", 2)));
1817 EXPECT_TRUE(matchAndVerifyResultTrue(
1818 "class C { ~C(); }; C::~C() {}",
1819 cxxDestructorDecl(hasAnyBody(compoundStmt())).bind("dtr"),
1820 std::make_unique<VerifyIdIsBoundTo<CXXDestructorDecl>>("dtr", 2)));
1821}
1822
1823TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
1824 // The simplest case: every compound statement is in a function
1825 // definition, and the function body itself must be a compound
1826 // statement.
1827 EXPECT_TRUE(matches("void f() { for (;;); }",
1828 compoundStmt(hasAnySubstatement(forStmt()))));
1829}
1830
1831TEST(HasAnySubstatement, IsNotRecursive) {
1832 // It's really "has any immediate substatement".
1833 EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
1834 compoundStmt(hasAnySubstatement(forStmt()))));
1835}
1836
1837TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
1838 EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
1839 compoundStmt(hasAnySubstatement(forStmt()))));
1840}
1841
1842TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
1843 EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
1844 compoundStmt(hasAnySubstatement(forStmt()))));
1845}
1846
1847TEST(Member, MatchesMemberAllocationFunction) {
1848 // Fails in C++11 mode
1849 EXPECT_TRUE(matchesConditionally(
1850 "namespace std { typedef typeof(sizeof(int)) size_t; }"
1851 "class X { void *operator new(std::size_t); };",
1852 cxxMethodDecl(ofClass(hasName("X"))), true, {"-std=gnu++03"}));
1853
1854 EXPECT_TRUE(matches("class X { void operator delete(void*); };",
1855 cxxMethodDecl(ofClass(hasName("X")))));
1856
1857 // Fails in C++11 mode
1858 EXPECT_TRUE(matchesConditionally(
1859 "namespace std { typedef typeof(sizeof(int)) size_t; }"
1860 "class X { void operator delete[](void*, std::size_t); };",
1861 cxxMethodDecl(ofClass(hasName("X"))), true, {"-std=gnu++03"}));
1862}
1863
1864TEST(HasDestinationType, MatchesSimpleCase) {
1865 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
1866 cxxStaticCastExpr(hasDestinationType(
1867 pointsTo(TypeMatcher(anything()))))));
1868}
1869
1870TEST(HasImplicitDestinationType, MatchesSimpleCase) {
1871 // This test creates an implicit const cast.
1872 EXPECT_TRUE(matches(
1873 "int x; const int i = x;",
1874 traverse(TK_AsIs,
1875 implicitCastExpr(hasImplicitDestinationType(isInteger())))));
1876 // This test creates an implicit array-to-pointer cast.
1877 EXPECT_TRUE(
1878 matches("int arr[3]; int *p = arr;",
1879 traverse(TK_AsIs, implicitCastExpr(hasImplicitDestinationType(
1880 pointsTo(TypeMatcher(anything())))))));
1881}
1882
1883TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
1884 // This test creates an implicit cast from int to char.
1885 EXPECT_TRUE(notMatches("char c = 0;",
1886 implicitCastExpr(hasImplicitDestinationType(
1887 unless(anything())))));
1888 // This test creates an implicit array-to-pointer cast.
1889 EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
1890 implicitCastExpr(hasImplicitDestinationType(
1891 unless(anything())))));
1892}
1893
1894TEST(Matcher, IgnoresElidableConstructors) {
1895 EXPECT_TRUE(
1896 matches("struct H {};"
1897 "template<typename T> H B(T A);"
1898 "void f() {"
1899 " H D1;"
1900 " D1 = B(B(1));"
1901 "}",
1902 cxxOperatorCallExpr(hasArgument(
1903 1, callExpr(hasArgument(
1904 0, ignoringElidableConstructorCall(callExpr()))))),
1905 langCxx11OrLater()));
1906 EXPECT_TRUE(
1907 matches("struct H {};"
1908 "template<typename T> H B(T A);"
1909 "void f() {"
1910 " H D1;"
1911 " D1 = B(1);"
1912 "}",
1913 cxxOperatorCallExpr(hasArgument(
1914 1, callExpr(hasArgument(0, ignoringElidableConstructorCall(
1915 integerLiteral()))))),
1916 langCxx11OrLater()));
1917 EXPECT_TRUE(matches(
1918 "struct H {};"
1919 "H G();"
1920 "void f() {"
1921 " H D = G();"
1922 "}",
1923 varDecl(hasInitializer(anyOf(
1924 ignoringElidableConstructorCall(callExpr()),
1925 exprWithCleanups(has(ignoringElidableConstructorCall(callExpr())))))),
1926 langCxx11OrLater()));
1927}
1928
1929TEST(Matcher, IgnoresElidableInReturn) {
1930 auto matcher = expr(ignoringElidableConstructorCall(declRefExpr()));
1931 EXPECT_TRUE(matches("struct H {};"
1932 "H f() {"
1933 " H g;"
1934 " return g;"
1935 "}",
1936 matcher, langCxx11OrLater()));
1937 EXPECT_TRUE(notMatches("struct H {};"
1938 "H f() {"
1939 " return H();"
1940 "}",
1941 matcher, langCxx11OrLater()));
1942}
1943
1944TEST(Matcher, IgnoreElidableConstructorDoesNotMatchConstructors) {
1945 EXPECT_TRUE(matches("struct H {};"
1946 "void f() {"
1947 " H D;"
1948 "}",
1949 varDecl(hasInitializer(
1950 ignoringElidableConstructorCall(cxxConstructExpr()))),
1951 langCxx11OrLater()));
1952}
1953
1954TEST(Matcher, IgnoresElidableDoesNotPreventMatches) {
1955 EXPECT_TRUE(matches("void f() {"
1956 " int D = 10;"
1957 "}",
1958 expr(ignoringElidableConstructorCall(integerLiteral())),
1959 langCxx11OrLater()));
1960}
1961
1962TEST(Matcher, IgnoresElidableInVarInit) {
1963 auto matcher =
1964 varDecl(hasInitializer(ignoringElidableConstructorCall(callExpr())));
1965 EXPECT_TRUE(matches("struct H {};"
1966 "H G();"
1967 "void f(H D = G()) {"
1968 " return;"
1969 "}",
1970 matcher, langCxx11OrLater()));
1971 EXPECT_TRUE(matches("struct H {};"
1972 "H G();"
1973 "void f() {"
1974 " H D = G();"
1975 "}",
1976 matcher, langCxx11OrLater()));
1977}
1978
1979TEST(IgnoringImplicit, MatchesImplicit) {
1980 EXPECT_TRUE(matches("class C {}; C a = C();",
1981 varDecl(has(ignoringImplicit(cxxConstructExpr())))));
1982}
1983
1984TEST(IgnoringImplicit, MatchesNestedImplicit) {
1985 StringRef Code = R"(
1986
1987struct OtherType;
1988
1989struct SomeType
1990{
1991 SomeType() {}
1992 SomeType(const OtherType&) {}
1993 SomeType& operator=(OtherType const&) { return *this; }
1994};
1995
1996struct OtherType
1997{
1998 OtherType() {}
1999 ~OtherType() {}
2000};
2001
2002OtherType something()
2003{
2004 return {};
2005}
2006
2007int main()
2008{
2009 SomeType i = something();
2010}
2011)";
2012 EXPECT_TRUE(matches(
2013 Code,
2014 traverse(TK_AsIs,
2015 varDecl(hasName("i"),
2016 hasInitializer(exprWithCleanups(has(cxxConstructExpr(
2017 has(expr(ignoringImplicit(cxxConstructExpr(has(
2018 expr(ignoringImplicit(callExpr())))))))))))))));
2019}
2020
2021TEST(IgnoringImplicit, DoesNotMatchIncorrectly) {
2022 EXPECT_TRUE(notMatches("class C {}; C a = C();",
2023 traverse(TK_AsIs, varDecl(has(cxxConstructExpr())))));
2024}
2025
2026TEST(Traversal, traverseMatcher) {
2027
2028 StringRef VarDeclCode = R"cpp(
2029void foo()
2030{
2031 int i = 3.0;
2032}
2033)cpp";
2034
2035 auto Matcher = varDecl(hasInitializer(floatLiteral()));
2036
2037 EXPECT_TRUE(notMatches(VarDeclCode, traverse(TK_AsIs, Matcher)));
2038 EXPECT_TRUE(
2039 matches(VarDeclCode, traverse(TK_IgnoreUnlessSpelledInSource, Matcher)));
2040
2041 auto ParentMatcher = floatLiteral(hasParent(varDecl(hasName("i"))));
2042
2043 EXPECT_TRUE(notMatches(VarDeclCode, traverse(TK_AsIs, ParentMatcher)));
2044 EXPECT_TRUE(matches(VarDeclCode,
2045 traverse(TK_IgnoreUnlessSpelledInSource, ParentMatcher)));
2046
2047 EXPECT_TRUE(matches(
2048 VarDeclCode, decl(traverse(TK_AsIs, anyOf(cxxRecordDecl(), varDecl())))));
2049
2050 EXPECT_TRUE(
2051 matches(VarDeclCode,
2052 floatLiteral(traverse(TK_AsIs, hasParent(implicitCastExpr())))));
2053
2054 EXPECT_TRUE(
2055 matches(VarDeclCode, floatLiteral(traverse(TK_IgnoreUnlessSpelledInSource,
2056 hasParent(varDecl())))));
2057
2058 EXPECT_TRUE(
2059 matches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2060 unless(parmVarDecl())))));
2061
2062 EXPECT_TRUE(
2063 notMatches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2064 has(implicitCastExpr())))));
2065
2066 EXPECT_TRUE(matches(VarDeclCode,
2067 varDecl(traverse(TK_AsIs, has(implicitCastExpr())))));
2068
2069 EXPECT_TRUE(matches(
2070 VarDeclCode, traverse(TK_IgnoreUnlessSpelledInSource,
2071 // The has() below strips away the ImplicitCastExpr
2072 // before the traverse(AsIs) gets to process it.
2073 varDecl(has(traverse(TK_AsIs, floatLiteral()))))));
2074
2075 EXPECT_TRUE(
2076 matches(VarDeclCode, functionDecl(traverse(TK_AsIs, hasName("foo")))));
2077
2078 EXPECT_TRUE(matches(
2079 VarDeclCode,
2080 functionDecl(traverse(TK_IgnoreUnlessSpelledInSource, hasName("foo")))));
2081
2082 EXPECT_TRUE(matches(
2083 VarDeclCode, functionDecl(traverse(TK_AsIs, hasAnyName("foo", "bar")))));
2084
2085 EXPECT_TRUE(
2086 matches(VarDeclCode, functionDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2087 hasAnyName("foo", "bar")))));
2088
2089 StringRef Code = R"cpp(
2090void foo(int a)
2091{
2092 int i = 3.0 + a;
2093}
2094void bar()
2095{
2096 foo(7.0);
2097}
2098)cpp";
2099 EXPECT_TRUE(
2100 matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource,
2101 hasArgument(0, floatLiteral())))));
2102
2103 EXPECT_TRUE(
2104 matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource,
2105 hasAnyArgument(floatLiteral())))));
2106
2107 EXPECT_TRUE(matches(
2108 R"cpp(
2109void takesBool(bool){}
2110
2111template <typename T>
2112void neverInstantiatedTemplate() {
2113 takesBool(T{});
2114}
2115)cpp",
2116 traverse(TK_IgnoreUnlessSpelledInSource,
2117 callExpr(unless(callExpr(hasDeclaration(functionDecl())))))));
2118
2119 EXPECT_TRUE(
2120 matches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2121 hasType(builtinType())))));
2122
2123 EXPECT_TRUE(
2124 matches(VarDeclCode,
2125 functionDecl(hasName("foo"),
2126 traverse(TK_AsIs, hasDescendant(floatLiteral())))));
2127
2128 EXPECT_TRUE(notMatches(
2129 Code, traverse(TK_AsIs, floatLiteral(hasParent(callExpr(
2130 callee(functionDecl(hasName("foo")))))))));
2131 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2132 floatLiteral(hasParent(callExpr(callee(
2133 functionDecl(hasName("foo")))))))));
2134
2135 Code = R"cpp(
2136void foo()
2137{
2138 int i = (3);
2139}
2140)cpp";
2141 EXPECT_TRUE(matches(
2142 Code, traverse(TK_IgnoreUnlessSpelledInSource,
2143 varDecl(hasInitializer(integerLiteral(equals(3)))))));
2144 EXPECT_TRUE(matches(
2145 Code,
2146 traverse(TK_IgnoreUnlessSpelledInSource,
2147 integerLiteral(equals(3), hasParent(varDecl(hasName("i")))))));
2148
2149 Code = R"cpp(
2150const char *SomeString{"str"};
2151)cpp";
2152 EXPECT_TRUE(
2153 matches(Code, traverse(TK_AsIs, stringLiteral(hasParent(implicitCastExpr(
2154 hasParent(initListExpr())))))));
2155 EXPECT_TRUE(
2156 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2157 stringLiteral(hasParent(initListExpr())))));
2158
2159 Code = R"cpp(
2160struct String
2161{
2162 String(const char*, int = -1) {}
2163};
2164
2165void stringConstruct()
2166{
2167 String s = "foo";
2168 s = "bar";
2169}
2170)cpp";
2171 EXPECT_TRUE(matches(
2172 Code,
2173 traverse(
2174 TK_AsIs,
2175 functionDecl(
2176 hasName("stringConstruct"),
2177 hasDescendant(varDecl(
2178 hasName("s"),
2179 hasInitializer(ignoringImplicit(cxxConstructExpr(hasArgument(
2180 0, ignoringImplicit(cxxConstructExpr(hasArgument(
2181 0, ignoringImplicit(stringLiteral()))))))))))))));
2182
2183 EXPECT_TRUE(matches(
2184 Code,
2185 traverse(
2186 TK_AsIs,
2187 functionDecl(hasName("stringConstruct"),
2188 hasDescendant(cxxOperatorCallExpr(
2189 isAssignmentOperator(),
2190 hasArgument(1, ignoringImplicit(
2191 cxxConstructExpr(hasArgument(
2192 0, ignoringImplicit(stringLiteral())))))
2193 ))))));
2194
2195 EXPECT_TRUE(matches(
2196 Code, traverse(TK_IgnoreUnlessSpelledInSource,
2197 functionDecl(hasName("stringConstruct"),
2198 hasDescendant(varDecl(
2199 hasName("s"),
2200 hasInitializer(stringLiteral())))))));
2201
2202 EXPECT_TRUE(
2203 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2204 functionDecl(hasName("stringConstruct"),
2205 hasDescendant(cxxOperatorCallExpr(
2206 isAssignmentOperator(),
2207 hasArgument(1, stringLiteral())))))));
2208
2209 Code = R"cpp(
2210
2211struct C1 {};
2212struct C2 { operator C1(); };
2213
2214void conversionOperator()
2215{
2216 C2* c2;
2217 C1 c1 = (*c2);
2218}
2219
2220)cpp";
2221 EXPECT_TRUE(matches(
2222 Code,
2223 traverse(
2224 TK_AsIs,
2225 functionDecl(
2226 hasName("conversionOperator"),
2227 hasDescendant(
2228 varDecl(
2229 hasName("c1"),
2230 hasInitializer(
2231 ignoringImplicit(cxxConstructExpr(hasArgument(
2232 0, ignoringImplicit(
2233 cxxMemberCallExpr(onImplicitObjectArgument(
2234 ignoringParenImpCasts(unaryOperator(
2235 hasOperatorName("*")))))))))))
2236 .bind("c1"))))));
2237
2238 EXPECT_TRUE(matches(
2239 Code,
2240 traverse(TK_IgnoreUnlessSpelledInSource,
2241 functionDecl(hasName("conversionOperator"),
2242 hasDescendant(varDecl(
2243 hasName("c1"), hasInitializer(unaryOperator(
2244 hasOperatorName("*")))))))));
2245
2246 Code = R"cpp(
2247
2248template <unsigned alignment>
2249void template_test() {
2250 static_assert(alignment, "");
2251}
2252void actual_template_test() {
2253 template_test<4>();
2254}
2255
2256)cpp";
2257 EXPECT_TRUE(matches(
2258 Code,
2259 traverse(TK_AsIs,
2260 staticAssertDecl(has(implicitCastExpr(has(
2261 substNonTypeTemplateParmExpr(has(integerLiteral())))))))));
2262 EXPECT_TRUE(matches(
2263 Code, traverse(TK_IgnoreUnlessSpelledInSource,
2264 staticAssertDecl(has(declRefExpr(
2265 to(nonTypeTemplateParmDecl(hasName("alignment"))),
2266 hasType(asString("unsigned int"))))))));
2267
2268 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, staticAssertDecl(hasDescendant(
2269 integerLiteral())))));
2270 EXPECT_FALSE(matches(
2271 Code, traverse(TK_IgnoreUnlessSpelledInSource,
2272 staticAssertDecl(hasDescendant(integerLiteral())))));
2273
2274 Code = R"cpp(
2275
2276struct OneParamCtor {
2277 explicit OneParamCtor(int);
2278};
2279struct TwoParamCtor {
2280 explicit TwoParamCtor(int, int);
2281};
2282
2283void varDeclCtors() {
2284 {
2285 auto var1 = OneParamCtor(5);
2286 auto var2 = TwoParamCtor(6, 7);
2287 }
2288 {
2289 OneParamCtor var3(5);
2290 TwoParamCtor var4(6, 7);
2291 }
2292 int i = 0;
2293 {
2294 auto var5 = OneParamCtor(i);
2295 auto var6 = TwoParamCtor(i, 7);
2296 }
2297 {
2298 OneParamCtor var7(i);
2299 TwoParamCtor var8(i, 7);
2300 }
2301}
2302
2303)cpp";
2304 EXPECT_TRUE(matches(
2305 Code,
2306 traverse(TK_AsIs, varDecl(hasName("var1"), hasInitializer(hasDescendant(
2307 cxxConstructExpr()))))));
2308 EXPECT_TRUE(matches(
2309 Code,
2310 traverse(TK_AsIs, varDecl(hasName("var2"), hasInitializer(hasDescendant(
2311 cxxConstructExpr()))))));
2312 EXPECT_TRUE(matches(
2313 Code, traverse(TK_AsIs, varDecl(hasName("var3"),
2314 hasInitializer(cxxConstructExpr())))));
2315 EXPECT_TRUE(matches(
2316 Code, traverse(TK_AsIs, varDecl(hasName("var4"),
2317 hasInitializer(cxxConstructExpr())))));
2318 EXPECT_TRUE(matches(
2319 Code,
2320 traverse(TK_AsIs, varDecl(hasName("var5"), hasInitializer(hasDescendant(
2321 cxxConstructExpr()))))));
2322 EXPECT_TRUE(matches(
2323 Code,
2324 traverse(TK_AsIs, varDecl(hasName("var6"), hasInitializer(hasDescendant(
2325 cxxConstructExpr()))))));
2326 EXPECT_TRUE(matches(
2327 Code, traverse(TK_AsIs, varDecl(hasName("var7"),
2328 hasInitializer(cxxConstructExpr())))));
2329 EXPECT_TRUE(matches(
2330 Code, traverse(TK_AsIs, varDecl(hasName("var8"),
2331 hasInitializer(cxxConstructExpr())))));
2332
2333 EXPECT_TRUE(matches(
2334 Code,
2335 traverse(TK_IgnoreUnlessSpelledInSource,
2336 varDecl(hasName("var1"), hasInitializer(cxxConstructExpr())))));
2337 EXPECT_TRUE(matches(
2338 Code,
2339 traverse(TK_IgnoreUnlessSpelledInSource,
2340 varDecl(hasName("var2"), hasInitializer(cxxConstructExpr())))));
2341 EXPECT_TRUE(matches(
2342 Code,
2343 traverse(TK_IgnoreUnlessSpelledInSource,
2344 varDecl(hasName("var3"), hasInitializer(cxxConstructExpr())))));
2345 EXPECT_TRUE(matches(
2346 Code,
2347 traverse(TK_IgnoreUnlessSpelledInSource,
2348 varDecl(hasName("var4"), hasInitializer(cxxConstructExpr())))));
2349 EXPECT_TRUE(matches(
2350 Code,
2351 traverse(TK_IgnoreUnlessSpelledInSource,
2352 varDecl(hasName("var5"), hasInitializer(cxxConstructExpr())))));
2353 EXPECT_TRUE(matches(
2354 Code,
2355 traverse(TK_IgnoreUnlessSpelledInSource,
2356 varDecl(hasName("var6"), hasInitializer(cxxConstructExpr())))));
2357 EXPECT_TRUE(matches(
2358 Code,
2359 traverse(TK_IgnoreUnlessSpelledInSource,
2360 varDecl(hasName("var7"), hasInitializer(cxxConstructExpr())))));
2361 EXPECT_TRUE(matches(
2362 Code,
2363 traverse(TK_IgnoreUnlessSpelledInSource,
2364 varDecl(hasName("var8"), hasInitializer(cxxConstructExpr())))));
2365
2366 Code = R"cpp(
2367
2368template<typename T>
2369struct TemplStruct {
2370 TemplStruct() {}
2371 ~TemplStruct() {}
2372
2373 void outOfLine(T);
2374
2375private:
2376 T m_t;
2377};
2378
2379template<typename T>
2380void TemplStruct<T>::outOfLine(T)
2381{
2382
2383}
2384
2385template<typename T>
2386T timesTwo(T input)
2387{
2388 return input * 2;
2389}
2390
2391void instantiate()
2392{
2393 TemplStruct<int> ti;
2394 TemplStruct<double> td;
2395 (void)timesTwo<int>(2);
2396 (void)timesTwo<double>(2);
2397}
2398
2399template class TemplStruct<float>;
2400
2401extern template class TemplStruct<long>;
2402
2403template<> class TemplStruct<bool> {
2404 TemplStruct() {}
2405 ~TemplStruct() {}
2406
2407 void boolSpecializationMethodOnly() {}
2408private:
2409 bool m_t;
2410};
2411
2412template float timesTwo(float);
2413template<> bool timesTwo<bool>(bool){
2414 return true;
2415}
2416)cpp";
2417 {
2418 auto M = cxxRecordDecl(hasName("TemplStruct"),
2419 has(fieldDecl(hasType(asString("int")))));
2420 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2421 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2422 }
2423 {
2424 auto M = cxxRecordDecl(hasName("TemplStruct"),
2425 has(fieldDecl(hasType(asString("double")))));
2426 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2427 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2428 }
2429 {
2430 auto M =
2431 functionDecl(hasName("timesTwo"),
2432 hasParameter(0, parmVarDecl(hasType(asString("int")))));
2433 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2434 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2435 }
2436 {
2437 auto M =
2438 functionDecl(hasName("timesTwo"),
2439 hasParameter(0, parmVarDecl(hasType(asString("double")))));
2440 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2441 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2442 }
2443 {
2444 // Match on the integer literal in the explicit instantiation:
2445 auto MDef =
2446 functionDecl(hasName("timesTwo"),
2447 hasParameter(0, parmVarDecl(hasType(asString("float")))),
2448 hasDescendant(integerLiteral(equals(2))));
2449 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDef)));
2450 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDef)));
2451
2452 auto MTempl =
2453 functionDecl(hasName("timesTwo"),
2454 hasTemplateArgument(0, refersToType(asString("float"))));
2455 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MTempl)));
2456 // TODO: If we could match on explicit instantiations of function templates,
2457 // this would be EXPECT_TRUE. See Sema::ActOnExplicitInstantiation.
2458 EXPECT_FALSE(
2459 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MTempl)));
2460 }
2461 {
2462 auto M = functionDecl(hasName("timesTwo"),
2463 hasParameter(0, parmVarDecl(hasType(booleanType()))));
2464 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2465 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2466 }
2467 {
2468 // Match on the field within the explicit instantiation:
2469 auto MRecord = cxxRecordDecl(hasName("TemplStruct"),
2470 has(fieldDecl(hasType(asString("float")))));
2471 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MRecord)));
2472 EXPECT_FALSE(
2473 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MRecord)));
2474
2475 // Match on the explicit template instantiation itself:
2476 auto MTempl = classTemplateSpecializationDecl(
2477 hasName("TemplStruct"),
2478 hasTemplateArgument(0,
2479 templateArgument(refersToType(asString("float")))));
2480 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MTempl)));
2481 EXPECT_TRUE(
2482 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MTempl)));
2483 }
2484 {
2485 // The template argument is matchable, but the instantiation is not:
2486 auto M = classTemplateSpecializationDecl(
2487 hasName("TemplStruct"),
2488 hasTemplateArgument(0,
2489 templateArgument(refersToType(asString("float")))),
2490 has(cxxConstructorDecl(hasName("TemplStruct"))));
2491 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2492 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2493 }
2494 {
2495 // The template argument is matchable, but the instantiation is not:
2496 auto M = classTemplateSpecializationDecl(
2497 hasName("TemplStruct"),
2498 hasTemplateArgument(0,
2499 templateArgument(refersToType(asString("long")))),
2500 has(cxxConstructorDecl(hasName("TemplStruct"))));
2501 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2502 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2503 }
2504 {
2505 // Instantiated, out-of-line methods are not matchable.
2506 auto M =
2507 cxxMethodDecl(hasName("outOfLine"), isDefinition(),
2508 hasParameter(0, parmVarDecl(hasType(asString("float")))));
2509 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2510 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2511 }
2512 {
2513 // Explicit specialization is written in source and it matches:
2514 auto M = classTemplateSpecializationDecl(
2515 hasName("TemplStruct"),
2516 hasTemplateArgument(0, templateArgument(refersToType(booleanType()))),
2517 has(cxxConstructorDecl(hasName("TemplStruct"))),
2518 has(cxxMethodDecl(hasName("boolSpecializationMethodOnly"))));
2519 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2520 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2521 }
2522
2523 Code = R"cpp(
2524struct B {
2525 B(int);
2526};
2527
2528B func1() { return 42; }
2529 )cpp";
2530 {
2531 auto M = expr(ignoringImplicit(integerLiteral(equals(42)).bind("intLit")));
2532 EXPECT_TRUE(matchAndVerifyResultTrue(
2533 Code, traverse(TK_AsIs, M),
2534 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2535 EXPECT_TRUE(matchAndVerifyResultTrue(
2536 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2537 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2538 }
2539 {
2540 auto M = expr(unless(integerLiteral(equals(24)))).bind("intLit");
2541 EXPECT_TRUE(matchAndVerifyResultTrue(
2542 Code, traverse(TK_AsIs, M),
2543 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 7)));
2544 EXPECT_TRUE(matchAndVerifyResultTrue(
2545 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2546 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2547 }
2548 {
2549 auto M =
2550 expr(anyOf(integerLiteral(equals(42)).bind("intLit"), unless(expr())));
2551 EXPECT_TRUE(matchAndVerifyResultTrue(
2552 Code, traverse(TK_AsIs, M),
2553 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2554 EXPECT_TRUE(matchAndVerifyResultTrue(
2555 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2556 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2557 }
2558 {
2559 auto M = expr(allOf(integerLiteral(equals(42)).bind("intLit"), expr()));
2560 EXPECT_TRUE(matchAndVerifyResultTrue(
2561 Code, traverse(TK_AsIs, M),
2562 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2563 EXPECT_TRUE(matchAndVerifyResultTrue(
2564 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2565 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2566 }
2567 {
2568 auto M = expr(integerLiteral(equals(42)).bind("intLit"), expr());
2569 EXPECT_TRUE(matchAndVerifyResultTrue(
2570 Code, traverse(TK_AsIs, M),
2571 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2572 EXPECT_TRUE(matchAndVerifyResultTrue(
2573 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2574 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2575 }
2576 {
2577 auto M = expr(optionally(integerLiteral(equals(42)).bind("intLit")));
2578 EXPECT_TRUE(matchAndVerifyResultTrue(
2579 Code, traverse(TK_AsIs, M),
2580 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2581 EXPECT_TRUE(matchAndVerifyResultTrue(
2582 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2583 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2584 }
2585 {
2586 auto M = expr().bind("allExprs");
2587 EXPECT_TRUE(matchAndVerifyResultTrue(
2588 Code, traverse(TK_AsIs, M),
2589 std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 7)));
2590 EXPECT_TRUE(matchAndVerifyResultTrue(
2591 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2592 std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 1)));
2593 }
2594}
2595
2596TEST(Traversal, traverseNoImplicit) {
2597 StringRef Code = R"cpp(
2598struct NonTrivial {
2599 NonTrivial() {}
2600 NonTrivial(const NonTrivial&) {}
2601 NonTrivial& operator=(const NonTrivial&) { return *this; }
2602
2603 ~NonTrivial() {}
2604};
2605
2606struct NoSpecialMethods {
2607 NonTrivial nt;
2608};
2609
2610struct ContainsArray {
2611 NonTrivial arr[2];
2612 ContainsArray& operator=(const ContainsArray &other) = default;
2613};
2614
2615void copyIt()
2616{
2617 NoSpecialMethods nc1;
2618 NoSpecialMethods nc2(nc1);
2619 nc2 = nc1;
2620
2621 ContainsArray ca;
2622 ContainsArray ca2;
2623 ca2 = ca;
2624}
2625
2626struct HasCtorInits : NoSpecialMethods, NonTrivial
2627{
2628 int m_i;
2629 NonTrivial m_nt;
2630 HasCtorInits() : NoSpecialMethods(), m_i(42) {}
2631};
2632
2633struct CtorInitsNonTrivial : NonTrivial
2634{
2635 int m_i;
2636 NonTrivial m_nt;
2637 CtorInitsNonTrivial() : NonTrivial(), m_i(42) {}
2638};
2639
2640)cpp";
2641 {
2642 auto M = cxxRecordDecl(hasName("NoSpecialMethods"),
2643 has(cxxRecordDecl(hasName("NoSpecialMethods"))));
2644 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2645 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2646
2647 M = cxxRecordDecl(hasName("NoSpecialMethods"),
2648 has(cxxConstructorDecl(isCopyConstructor())));
2649 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2650 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2651
2652 M = cxxRecordDecl(hasName("NoSpecialMethods"),
2653 has(cxxMethodDecl(isCopyAssignmentOperator())));
2654 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2655 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2656
2657 M = cxxRecordDecl(hasName("NoSpecialMethods"),
2658 has(cxxConstructorDecl(isDefaultConstructor())));
2659 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2660 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2661
2662 M = cxxRecordDecl(hasName("NoSpecialMethods"), has(cxxDestructorDecl()));
2663 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2664 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2665
2666 M = cxxRecordDecl(hasName("NoSpecialMethods"),
2667 hasMethod(cxxConstructorDecl(isCopyConstructor())));
2668 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2669 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2670
2671 M = cxxRecordDecl(hasName("NoSpecialMethods"),
2672 hasMethod(cxxMethodDecl(isCopyAssignmentOperator())));
2673 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2674 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2675
2676 M = cxxRecordDecl(hasName("NoSpecialMethods"),
2677 hasMethod(cxxConstructorDecl(isDefaultConstructor())));
2678 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2679 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2680
2681 M = cxxRecordDecl(hasName("NoSpecialMethods"),
2682 hasMethod(cxxDestructorDecl()));
2683 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2684 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2685 }
2686 {
2687 // Because the copy-assignment operator is not spelled in the
2688 // source (ie, isImplicit()), we don't match it
2689 auto M =
2690 cxxOperatorCallExpr(hasType(cxxRecordDecl(hasName("NoSpecialMethods"))),
2691 callee(cxxMethodDecl(isCopyAssignmentOperator())));
2692 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2693 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2694 }
2695 {
2696 // Compiler generates a forStmt to copy the array
2697 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, forStmt())));
2698 EXPECT_FALSE(
2699 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, forStmt())));
2700 }
2701 {
2702 // The defaulted method declaration can be matched, but not its
2703 // definition, in IgnoreUnlessSpelledInSource mode
2704 auto MDecl = cxxMethodDecl(ofClass(cxxRecordDecl(hasName("ContainsArray"))),
2705 isCopyAssignmentOperator(), isDefaulted());
2706
2707 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDecl)));
2708 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDecl)));
2709
2710 auto MDef = cxxMethodDecl(MDecl, has(compoundStmt()));
2711
2712 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDef)));
2713 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDef)));
2714
2715 auto MBody = cxxMethodDecl(MDecl, hasBody(compoundStmt()));
2716
2717 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MBody)));
2718 EXPECT_FALSE(
2719 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MBody)));
2720
2721 auto MIsDefn = cxxMethodDecl(MDecl, isDefinition());
2722
2723 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MIsDefn)));
2724 EXPECT_TRUE(
2725 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MIsDefn)));
2726
2727 auto MIsInline = cxxMethodDecl(MDecl, isInline());
2728
2729 EXPECT_FALSE(matches(Code, traverse(TK_AsIs, MIsInline)));
2730 EXPECT_FALSE(
2731 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MIsInline)));
2732
2733 // The parameter of the defaulted method can still be matched.
2734 auto MParm =
2735 cxxMethodDecl(MDecl, hasParameter(0, parmVarDecl(hasName("other"))));
2736
2737 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MParm)));
2738 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MParm)));
2739 }
2740 {
2741 auto M =
2742 cxxConstructorDecl(hasName("HasCtorInits"),
2743 has(cxxCtorInitializer(forField(hasName("m_i")))));
2744 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2745 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2746 }
2747 {
2748 auto M =
2749 cxxConstructorDecl(hasName("HasCtorInits"),
2750 has(cxxCtorInitializer(forField(hasName("m_nt")))));
2751 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2752 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2753 }
2754 {
2755 auto M = cxxConstructorDecl(hasName("HasCtorInits"),
2756 hasAnyConstructorInitializer(cxxCtorInitializer(
2757 forField(hasName("m_nt")))));
2758 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2759 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2760 }
2761 {
2762 auto M =
2763 cxxConstructorDecl(hasName("HasCtorInits"),
2764 forEachConstructorInitializer(
2765 cxxCtorInitializer(forField(hasName("m_nt")))));
2766 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2767 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2768 }
2769 {
2770 auto M = cxxConstructorDecl(
2771 hasName("CtorInitsNonTrivial"),
2772 has(cxxCtorInitializer(withInitializer(cxxConstructExpr(
2773 hasDeclaration(cxxConstructorDecl(hasName("NonTrivial"))))))));
2774 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2775 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2776 }
2777 {
2778 auto M = cxxConstructorDecl(
2779 hasName("HasCtorInits"),
2780 has(cxxCtorInitializer(withInitializer(cxxConstructExpr(hasDeclaration(
2781 cxxConstructorDecl(hasName("NoSpecialMethods"))))))));
2782 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2783 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2784 }
2785 {
2786 auto M = cxxCtorInitializer(forField(hasName("m_nt")));
2787 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2788 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2789 }
2790
2791 Code = R"cpp(
2792 void rangeFor()
2793 {
2794 int arr[2];
2795 for (auto i : arr)
2796 {
2797 if (true)
2798 {
2799 }
2800 }
2801 }
2802 )cpp";
2803 {
2804 auto M = cxxForRangeStmt(has(binaryOperator(hasOperatorName("!="))));
2805 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2806 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2807 }
2808 {
2809 auto M =
2810 cxxForRangeStmt(hasDescendant(binaryOperator(hasOperatorName("+"))));
2811 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2812 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2813 }
2814 {
2815 auto M =
2816 cxxForRangeStmt(hasDescendant(unaryOperator(hasOperatorName("++"))));
2817 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2818 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2819 }
2820 {
2821 auto M = cxxForRangeStmt(has(declStmt()));
2822 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2823 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2824 }
2825 {
2826 auto M =
2827 cxxForRangeStmt(hasLoopVariable(varDecl(hasName("i"))),
2828 hasRangeInit(declRefExpr(to(varDecl(hasName("arr"))))));
2829 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2830 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2831 }
2832 {
2833 auto M = cxxForRangeStmt(unless(hasInitStatement(stmt())));
2834 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2835 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2836 }
2837 {
2838 auto M = cxxForRangeStmt(hasBody(stmt()));
2839 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2840 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2841 }
2842 {
2843 auto M = cxxForRangeStmt(hasDescendant(ifStmt()));
2844 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2845 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2846 }
2847 {
2848 EXPECT_TRUE(matches(
2849 Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt(
2850 hasSingleDecl(varDecl(hasName("i")))))))));
2851 EXPECT_TRUE(
2852 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2853 cxxForRangeStmt(has(varDecl(hasName("i")))))));
2854 }
2855 {
2856 EXPECT_TRUE(matches(
2857 Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt(hasSingleDecl(
2858 varDecl(hasInitializer(declRefExpr(
2859 to(varDecl(hasName("arr")))))))))))));
2860 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2861 cxxForRangeStmt(has(declRefExpr(
2862 to(varDecl(hasName("arr")))))))));
2863 }
2864 {
2865 auto M = cxxForRangeStmt(has(compoundStmt()));
2866 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2867 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2868 }
2869 {
2870 auto M = binaryOperator(hasOperatorName("!="));
2871 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2872 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2873 }
2874 {
2875 auto M = unaryOperator(hasOperatorName("++"));
2876 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2877 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2878 }
2879 {
2880 auto M = declStmt(hasSingleDecl(varDecl(matchesName("__range"))));
2881 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2882 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2883 }
2884 {
2885 auto M = declStmt(hasSingleDecl(varDecl(matchesName("__begin"))));
2886 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2887 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2888 }
2889 {
2890 auto M = declStmt(hasSingleDecl(varDecl(matchesName("__end"))));
2891 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2892 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2893 }
2894
2895 Code = R"cpp(
2896 struct Range {
2897 int* begin() const;
2898 int* end() const;
2899 };
2900 Range getRange(int);
2901
2902 void rangeFor()
2903 {
2904 for (auto i : getRange(42))
2905 {
2906 }
2907 }
2908 )cpp";
2909 {
2910 auto M = integerLiteral(equals(42));
2911 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2912 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2913 }
2914 {
2915 auto M = callExpr(hasDescendant(integerLiteral(equals(42))));
2916 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2917 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2918 }
2919 {
2920 auto M = compoundStmt(hasDescendant(integerLiteral(equals(42))));
2921 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2922 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2923 }
2924
2925 Code = R"cpp(
2926 void rangeFor()
2927 {
2928 int arr[2];
2929 for (auto& a = arr; auto i : a)
2930 {
2931
2932 }
2933 }
2934 )cpp";
2935 {
2936 auto M = cxxForRangeStmt(has(binaryOperator(hasOperatorName("!="))));
2937 EXPECT_TRUE(
2938 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
2939 EXPECT_FALSE(
2940 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2941 true, {"-std=c++20"}));
2942 }
2943 {
2944 auto M =
2945 cxxForRangeStmt(hasDescendant(binaryOperator(hasOperatorName("+"))));
2946 EXPECT_TRUE(
2947 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
2948 EXPECT_FALSE(
2949 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2950 true, {"-std=c++20"}));
2951 }
2952 {
2953 auto M =
2954 cxxForRangeStmt(hasDescendant(unaryOperator(hasOperatorName("++"))));
2955 EXPECT_TRUE(
2956 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
2957 EXPECT_FALSE(
2958 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2959 true, {"-std=c++20"}));
2960 }
2961 {
2962 auto M =
2963 cxxForRangeStmt(has(declStmt(hasSingleDecl(varDecl(hasName("i"))))));
2964 EXPECT_TRUE(
2965 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
2966 EXPECT_FALSE(
2967 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2968 true, {"-std=c++20"}));
2969 }
2970 {
2971 auto M = cxxForRangeStmt(
2972 hasInitStatement(declStmt(hasSingleDecl(varDecl(
2973 hasName("a"),
2974 hasInitializer(declRefExpr(to(varDecl(hasName("arr"))))))))),
2975 hasLoopVariable(varDecl(hasName("i"))),
2976 hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))));
2977 EXPECT_TRUE(
2978 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
2979 EXPECT_TRUE(
2980 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2981 true, {"-std=c++20"}));
2982 }
2983 {
2984 auto M = cxxForRangeStmt(
2985 has(declStmt(hasSingleDecl(varDecl(
2986 hasName("a"),
2987 hasInitializer(declRefExpr(to(varDecl(hasName("arr"))))))))),
2988 hasLoopVariable(varDecl(hasName("i"))),
2989 hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))));
2990 EXPECT_TRUE(
2991 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
2992 EXPECT_TRUE(
2993 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2994 true, {"-std=c++20"}));
2995 }
2996
2997 Code = R"cpp(
2998 struct Range {
2999 int* begin() const;
3000 int* end() const;
3001 };
3002 Range getRange(int);
3003
3004 int getNum(int);
3005
3006 void rangeFor()
3007 {
3008 for (auto j = getNum(42); auto i : getRange(j))
3009 {
3010 }
3011 }
3012 )cpp";
3013 {
3014 auto M = integerLiteral(equals(42));
3015 EXPECT_TRUE(
3016 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3017 EXPECT_TRUE(
3018 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3019 true, {"-std=c++20"}));
3020 }
3021 {
3022 auto M = compoundStmt(hasDescendant(integerLiteral(equals(42))));
3023 EXPECT_TRUE(
3024 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3025 EXPECT_TRUE(
3026 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3027 true, {"-std=c++20"}));
3028 }
3029
3030 Code = R"cpp(
3031void hasDefaultArg(int i, int j = 0)
3032{
3033}
3034void callDefaultArg()
3035{
3036 hasDefaultArg(42);
3037}
3038)cpp";
3039 auto hasDefaultArgCall = [](auto InnerMatcher) {
3040 return callExpr(callee(functionDecl(hasName("hasDefaultArg"))),
3041 InnerMatcher);
3042 };
3043 {
3044 auto M = hasDefaultArgCall(has(integerLiteral(equals(42))));
3045 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3046 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3047 }
3048 {
3049 auto M = hasDefaultArgCall(has(cxxDefaultArgExpr()));
3050 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3051 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3052 }
3053 {
3054 auto M = hasDefaultArgCall(argumentCountIs(2));
3055 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3056 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3057 }
3058 {
3059 auto M = hasDefaultArgCall(argumentCountIs(1));
3060 EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M)));
3061 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3062 }
3063 {
3064 auto M = hasDefaultArgCall(hasArgument(1, cxxDefaultArgExpr()));
3065 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3066 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3067 }
3068 {
3069 auto M = hasDefaultArgCall(hasAnyArgument(cxxDefaultArgExpr()));
3070 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3071 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3072 }
3073 Code = R"cpp(
3074struct A
3075{
3076 ~A();
3077private:
3078 int i;
3079};
3080
3081A::~A() = default;
3082)cpp";
3083 {
3084 auto M = cxxDestructorDecl(isDefaulted(),
3085 ofClass(cxxRecordDecl(has(fieldDecl()))));
3086 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3087 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3088 }
3089 Code = R"cpp(
3090struct S
3091{
3092 static constexpr bool getTrue() { return true; }
3093};
3094
3095struct A
3096{
3097 explicit(S::getTrue()) A();
3098};
3099
3100A::A() = default;
3101)cpp";
3102 {
3103 EXPECT_TRUE(matchesConditionally(
3104 Code,
3105 traverse(TK_AsIs,
3106 cxxConstructorDecl(
3107 isDefaulted(),
3108 hasExplicitSpecifier(expr(ignoringImplicit(
3109 callExpr(has(ignoringImplicit(declRefExpr())))))))),
3110 true, {"-std=c++20"}));
3111 EXPECT_TRUE(matchesConditionally(
3112 Code,
3113 traverse(TK_IgnoreUnlessSpelledInSource,
3114 cxxConstructorDecl(
3115 isDefaulted(),
3116 hasExplicitSpecifier(callExpr(has(declRefExpr()))))),
3117 true, {"-std=c++20"}));
3118 }
3119}
3120
3121template <typename MatcherT>
3122bool matcherTemplateWithBinding(StringRef Code, const MatcherT &M) {
3123 return matchAndVerifyResultTrue(
3124 Code, M.bind("matchedStmt"),
3125 std::make_unique<VerifyIdIsBoundTo<ReturnStmt>>("matchedStmt", 1));
3126}
3127
3128TEST(Traversal, traverseWithBinding) {
3129 // Some existing matcher code expects to take a matcher as a
3130 // template arg and bind to it. Verify that that works.
3131
3132 llvm::StringRef Code = R"cpp(
3133int foo()
3134{
3135 return 42.0;
3136}
3137)cpp";
3138 EXPECT_TRUE(matcherTemplateWithBinding(
3139 Code, traverse(TK_AsIs,
3140 returnStmt(has(implicitCastExpr(has(floatLiteral())))))));
3141}
3142
3143TEST(Traversal, traverseMatcherNesting) {
3144
3145 StringRef Code = R"cpp(
3146float bar(int i)
3147{
3148 return i;
3149}
3150
3151void foo()
3152{
3153 bar(bar(3.0));
3154}
3155)cpp";
3156
3157 EXPECT_TRUE(
3158 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
3159 callExpr(has(callExpr(traverse(
3160 TK_AsIs, callExpr(has(implicitCastExpr(
3161 has(floatLiteral())))))))))));
3162
3163 EXPECT_TRUE(matches(
3164 Code,
3165 traverse(TK_IgnoreUnlessSpelledInSource,
3166 traverse(TK_AsIs, implicitCastExpr(has(floatLiteral()))))));
3167}
3168
3169TEST(Traversal, traverseMatcherThroughImplicit) {
3170 StringRef Code = R"cpp(
3171struct S {
3172 S(int x);
3173};
3174
3175void constructImplicit() {
3176 int a = 8;
3177 S s(a);
3178}
3179 )cpp";
3180
3181 auto Matcher = traverse(TK_IgnoreUnlessSpelledInSource, implicitCastExpr());
3182
3183 // Verfiy that it does not segfault
3184 EXPECT_FALSE(matches(Code, Matcher));
3185}
3186
3187TEST(Traversal, traverseMatcherThroughMemoization) {
3188
3189 StringRef Code = R"cpp(
3190void foo()
3191{
3192 int i = 3.0;
3193}
3194 )cpp";
3195
3196 auto Matcher = varDecl(hasInitializer(floatLiteral()));
3197
3198 // Matchers such as hasDescendant memoize their result regarding AST
3199 // nodes. In the matcher below, the first use of hasDescendant(Matcher)
3200 // fails, and the use of it inside the traverse() matcher should pass
3201 // causing the overall matcher to be a true match.
3202 // This test verifies that the first false result is not re-used, which
3203 // would cause the overall matcher to be incorrectly false.
3204
3205 EXPECT_TRUE(matches(
3206 Code,
3207 functionDecl(anyOf(hasDescendant(Matcher),
3208 traverse(TK_IgnoreUnlessSpelledInSource,
3209 functionDecl(hasDescendant(Matcher)))))));
3210}
3211
3212TEST(Traversal, traverseUnlessSpelledInSource) {
3213
3214 StringRef Code = R"cpp(
3215
3216struct A
3217{
3218};
3219
3220struct B
3221{
3222 B(int);
3223 B(A const& a);
3224 B();
3225};
3226
3227struct C
3228{
3229 operator B();
3230};
3231
3232B func1() {
3233 return 42;
3234}
3235
3236B func2() {
3237 return B{42};
3238}
3239
3240B func3() {
3241 return B(42);
3242}
3243
3244B func4() {
3245 return B();
3246}
3247
3248B func5() {
3249 return B{};
3250}
3251
3252B func6() {
3253 return C();
3254}
3255
3256B func7() {
3257 return A();
3258}
3259
3260B func8() {
3261 return C{};
3262}
3263
3264B func9() {
3265 return A{};
3266}
3267
3268B func10() {
3269 A a;
3270 return a;
3271}
3272
3273B func11() {
3274 B b;
3275 return b;
3276}
3277
3278B func12() {
3279 C c;
3280 return c;
3281}
3282
3283void func13() {
3284 int a = 0;
3285 int c = 0;
3286
3287 [a, b = c](int d) { int e = d; };
3288}
3289
3290void func14() {
3291 [] <typename TemplateType> (TemplateType t, TemplateType u) { int e = t + u; };
3292 float i = 42.0;
3293}
3294
3295void func15() {
3296 int count = 0;
3297 auto l = [&] { ++count; };
3298 (void)l;
3299}
3300
3301)cpp";
3302
3303 EXPECT_TRUE(
3304 matches(Code,
3305 traverse(TK_IgnoreUnlessSpelledInSource,
3306 returnStmt(forFunction(functionDecl(hasName("func1"))),
3307 hasReturnValue(integerLiteral(equals(42))))),
3308 langCxx20OrLater()));
3309
3310 EXPECT_TRUE(
3311 matches(Code,
3312 traverse(TK_IgnoreUnlessSpelledInSource,
3313 integerLiteral(equals(42),
3314 hasParent(returnStmt(forFunction(
3315 functionDecl(hasName("func1"))))))),
3316 langCxx20OrLater()));
3317
3318 EXPECT_TRUE(matches(
3319 Code,
3320 traverse(TK_IgnoreUnlessSpelledInSource,
3321 returnStmt(forFunction(functionDecl(hasName("func2"))),
3322 hasReturnValue(cxxTemporaryObjectExpr(
3323 hasArgument(0, integerLiteral(equals(42))))))),
3324 langCxx20OrLater()));
3325 EXPECT_TRUE(matches(
3326 Code,
3327 traverse(
3328 TK_IgnoreUnlessSpelledInSource,
3329 integerLiteral(equals(42),
3330 hasParent(cxxTemporaryObjectExpr(hasParent(returnStmt(
3331 forFunction(functionDecl(hasName("func2"))))))))),
3332 langCxx20OrLater()));
3333
3334 EXPECT_TRUE(
3335 matches(Code,
3336 traverse(TK_IgnoreUnlessSpelledInSource,
3337 returnStmt(forFunction(functionDecl(hasName("func3"))),
3338 hasReturnValue(cxxConstructExpr(hasArgument(
3339 0, integerLiteral(equals(42))))))),
3340 langCxx20OrLater()));
3341
3342 EXPECT_TRUE(matches(
3343 Code,
3344 traverse(
3345 TK_IgnoreUnlessSpelledInSource,
3346 integerLiteral(equals(42),
3347 hasParent(cxxConstructExpr(hasParent(returnStmt(
3348 forFunction(functionDecl(hasName("func3"))))))))),
3349 langCxx20OrLater()));
3350
3351 EXPECT_TRUE(
3352 matches(Code,
3353 traverse(TK_IgnoreUnlessSpelledInSource,
3354 returnStmt(forFunction(functionDecl(hasName("func4"))),
3355 hasReturnValue(cxxTemporaryObjectExpr()))),
3356 langCxx20OrLater()));
3357
3358 EXPECT_TRUE(
3359 matches(Code,
3360 traverse(TK_IgnoreUnlessSpelledInSource,
3361 returnStmt(forFunction(functionDecl(hasName("func5"))),
3362 hasReturnValue(cxxTemporaryObjectExpr()))),
3363 langCxx20OrLater()));
3364
3365 EXPECT_TRUE(
3366 matches(Code,
3367 traverse(TK_IgnoreUnlessSpelledInSource,
3368 returnStmt(forFunction(functionDecl(hasName("func6"))),
3369 hasReturnValue(cxxTemporaryObjectExpr()))),
3370 langCxx20OrLater()));
3371
3372 EXPECT_TRUE(
3373 matches(Code,
3374 traverse(TK_IgnoreUnlessSpelledInSource,
3375 returnStmt(forFunction(functionDecl(hasName("func7"))),
3376 hasReturnValue(cxxTemporaryObjectExpr()))),
3377 langCxx20OrLater()));
3378
3379 EXPECT_TRUE(
3380 matches(Code,
3381 traverse(TK_IgnoreUnlessSpelledInSource,
3382 returnStmt(forFunction(functionDecl(hasName("func8"))),
3383 hasReturnValue(cxxFunctionalCastExpr(
3384 hasSourceExpression(initListExpr()))))),
3385 langCxx20OrLater()));
3386
3387 EXPECT_TRUE(
3388 matches(Code,
3389 traverse(TK_IgnoreUnlessSpelledInSource,
3390 returnStmt(forFunction(functionDecl(hasName("func9"))),
3391 hasReturnValue(cxxFunctionalCastExpr(
3392 hasSourceExpression(initListExpr()))))),
3393 langCxx20OrLater()));
3394
3395 EXPECT_TRUE(matches(
3396 Code,
3397 traverse(
3398 TK_IgnoreUnlessSpelledInSource,
3399 returnStmt(forFunction(functionDecl(hasName("func10"))),
3400 hasReturnValue(declRefExpr(to(varDecl(hasName("a"))))))),
3401 langCxx20OrLater()));
3402
3403 EXPECT_TRUE(
3404 matches(Code,
3405 traverse(TK_IgnoreUnlessSpelledInSource,
3406 declRefExpr(to(varDecl(hasName("a"))),
3407 hasParent(returnStmt(forFunction(
3408 functionDecl(hasName("func10"))))))),
3409 langCxx20OrLater()));
3410
3411 EXPECT_TRUE(matches(
3412 Code,
3413 traverse(
3414 TK_IgnoreUnlessSpelledInSource,
3415 returnStmt(forFunction(functionDecl(hasName("func11"))),
3416 hasReturnValue(declRefExpr(to(varDecl(hasName("b"))))))),
3417 langCxx20OrLater()));
3418
3419 EXPECT_TRUE(
3420 matches(Code,
3421 traverse(TK_IgnoreUnlessSpelledInSource,
3422 declRefExpr(to(varDecl(hasName("b"))),
3423 hasParent(returnStmt(forFunction(
3424 functionDecl(hasName("func11"))))))),
3425 langCxx20OrLater()));
3426
3427 EXPECT_TRUE(matches(
3428 Code,
3429 traverse(
3430 TK_IgnoreUnlessSpelledInSource,
3431 returnStmt(forFunction(functionDecl(hasName("func12"))),
3432 hasReturnValue(declRefExpr(to(varDecl(hasName("c"))))))),
3433 langCxx20OrLater()));
3434
3435 EXPECT_TRUE(
3436 matches(Code,
3437 traverse(TK_IgnoreUnlessSpelledInSource,
3438 declRefExpr(to(varDecl(hasName("c"))),
3439 hasParent(returnStmt(forFunction(
3440 functionDecl(hasName("func12"))))))),
3441 langCxx20OrLater()));
3442
3443 EXPECT_TRUE(matches(
3444 Code,
3445 traverse(
3446 TK_IgnoreUnlessSpelledInSource,
3447 lambdaExpr(forFunction(functionDecl(hasName("func13"))),
3448 has(compoundStmt(hasDescendant(varDecl(hasName("e"))))),
3449 has(declRefExpr(to(varDecl(hasName("a"))))),
3450 has(varDecl(hasName("b"), hasInitializer(declRefExpr(to(
3451 varDecl(hasName("c"))))))),
3452 has(parmVarDecl(hasName("d"))))),
3453 langCxx20OrLater()));
3454
3455 EXPECT_TRUE(
3456 matches(Code,
3457 traverse(TK_IgnoreUnlessSpelledInSource,
3458 declRefExpr(to(varDecl(hasName("a"))),
3459 hasParent(lambdaExpr(forFunction(
3460 functionDecl(hasName("func13"))))))),
3461 langCxx20OrLater()));
3462
3463 EXPECT_TRUE(matches(
3464 Code,
3465 traverse(TK_IgnoreUnlessSpelledInSource,
3466 varDecl(hasName("b"),
3467 hasInitializer(declRefExpr(to(varDecl(hasName("c"))))),
3468 hasParent(lambdaExpr(
3469 forFunction(functionDecl(hasName("func13"))))))),
3470 langCxx20OrLater()));
3471
3472 EXPECT_TRUE(matches(
3473 Code,
3474 traverse(TK_IgnoreUnlessSpelledInSource,
3475 lambdaExpr(forFunction(functionDecl(hasName("func14"))),
3476 has(templateTypeParmDecl(hasName("TemplateType"))))),
3477 langCxx20OrLater()));
3478
3479 EXPECT_TRUE(matches(
3480 Code,
3481 traverse(TK_IgnoreUnlessSpelledInSource,
3482 functionDecl(hasName("func14"), hasDescendant(floatLiteral()))),
3483 langCxx20OrLater()));
3484
3485 EXPECT_TRUE(matches(
3486 Code,
3487 traverse(TK_IgnoreUnlessSpelledInSource,
3488 compoundStmt(
3489 hasDescendant(varDecl(hasName("count")).bind("countVar")),
3490 hasDescendant(
3491 declRefExpr(to(varDecl(equalsBoundNode("countVar"))))))),
3492 langCxx20OrLater()));
3493
3494 Code = R"cpp(
3495void foo() {
3496 int explicit_captured = 0;
3497 int implicit_captured = 0;
3498 auto l = [&, explicit_captured](int i) {
3499 if (i || explicit_captured || implicit_captured) return;
3500 };
3501}
3502)cpp";
3503
3504 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, ifStmt())));
3505 EXPECT_TRUE(
3506 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, ifStmt())));
3507
3508 auto lambdaExplicitCapture = declRefExpr(
3509 to(varDecl(hasName("explicit_captured"))), unless(hasAncestor(ifStmt())));
3510 auto lambdaImplicitCapture = declRefExpr(
3511 to(varDecl(hasName("implicit_captured"))), unless(hasAncestor(ifStmt())));
3512
3513 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, lambdaExplicitCapture)));
3514 EXPECT_TRUE(matches(
3515 Code, traverse(TK_IgnoreUnlessSpelledInSource, lambdaExplicitCapture)));
3516
3517 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, lambdaImplicitCapture)));
3518 EXPECT_FALSE(matches(
3519 Code, traverse(TK_IgnoreUnlessSpelledInSource, lambdaImplicitCapture)));
3520
3521 Code = R"cpp(
3522struct S {};
3523
3524struct HasOpEq
3525{
3526 bool operator==(const S& other)
3527 {
3528 return true;
3529 }
3530};
3531
3532void binop()
3533{
3534 HasOpEq s1;
3535 S s2;
3536 if (s1 != s2)
3537 return;
3538}
3539)cpp";
3540 {
3541 auto M = unaryOperator(
3542 hasOperatorName("!"),
3543 has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="))));
3544 EXPECT_TRUE(
3545 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3546 EXPECT_FALSE(
3547 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3548 true, {"-std=c++20"}));
3549 }
3550 {
3551 auto M = declRefExpr(to(varDecl(hasName("s1"))));
3552 EXPECT_TRUE(
3553 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3554 EXPECT_TRUE(
3555 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3556 true, {"-std=c++20"}));
3557 }
3558 {
3559 auto M = cxxOperatorCallExpr(hasOverloadedOperatorName("=="));
3560 EXPECT_TRUE(
3561 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3562 EXPECT_FALSE(
3563 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3564 true, {"-std=c++20"}));
3565 }
3566 {
3567 auto M = cxxOperatorCallExpr(hasOverloadedOperatorName("!="));
3568 EXPECT_FALSE(
3569 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3570 EXPECT_FALSE(
3571 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3572 true, {"-std=c++20"}));
3573 }
3574 auto withDescendants = [](StringRef lName, StringRef rName) {
3575 return stmt(hasDescendant(declRefExpr(to(varDecl(hasName(lName))))),
3576 hasDescendant(declRefExpr(to(varDecl(hasName(rName))))));
3577 };
3578 {
3579 auto M = cxxRewrittenBinaryOperator(withDescendants("s1", "s2"));
3580 EXPECT_TRUE(
3581 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3582 EXPECT_TRUE(
3583 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3584 true, {"-std=c++20"}));
3585 }
3586 {
3587 auto M = cxxRewrittenBinaryOperator(
3588 has(declRefExpr(to(varDecl(hasName("s1"))))),
3589 has(declRefExpr(to(varDecl(hasName("s2"))))));
3590 EXPECT_FALSE(
3591 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3592 EXPECT_TRUE(
3593 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3594 true, {"-std=c++20"}));
3595 }
3596 {
3597 EXPECT_TRUE(matchesConditionally(
3598 Code,
3599 traverse(TK_AsIs,
3600 cxxRewrittenBinaryOperator(
3601 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
3602 isComparisonOperator(),
3603 hasLHS(ignoringImplicit(
3604 declRefExpr(to(varDecl(hasName("s1")))))),
3605 hasRHS(ignoringImplicit(
3606 declRefExpr(to(varDecl(hasName("s2")))))),
3607 hasEitherOperand(ignoringImplicit(
3608 declRefExpr(to(varDecl(hasName("s2")))))),
3609 hasOperands(ignoringImplicit(
3610 declRefExpr(to(varDecl(hasName("s1"))))),
3611 ignoringImplicit(declRefExpr(
3612 to(varDecl(hasName("s2")))))))),
3613 true, {"-std=c++20"}));
3614 EXPECT_TRUE(matchesConditionally(
3615 Code,
3616 traverse(TK_IgnoreUnlessSpelledInSource,
3617 cxxRewrittenBinaryOperator(
3618 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
3619 isComparisonOperator(),
3620 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
3621 hasRHS(declRefExpr(to(varDecl(hasName("s2"))))),
3622 hasEitherOperand(declRefExpr(to(varDecl(hasName("s2"))))),
3623 hasOperands(declRefExpr(to(varDecl(hasName("s1")))),
3624 declRefExpr(to(varDecl(hasName("s2"))))))),
3625 true, {"-std=c++20"}));
3626 }
3627
3628 Code = R"cpp(
3629namespace std {
3630struct strong_ordering {
3631 int n;
3632 constexpr operator int() const { return n; }
3633 static const strong_ordering equal, greater, less;
3634};
3635constexpr strong_ordering strong_ordering::equal = {0};
3636constexpr strong_ordering strong_ordering::greater = {1};
3637constexpr strong_ordering strong_ordering::less = {-1};
3638}
3639
3640struct HasSpaceshipMem {
3641 int a;
3642 constexpr auto operator<=>(const HasSpaceshipMem&) const = default;
3643};
3644
3645void binop()
3646{
3647 HasSpaceshipMem hs1, hs2;
3648 if (hs1 == hs2)
3649 return;
3650
3651 HasSpaceshipMem hs3, hs4;
3652 if (hs3 != hs4)
3653 return;
3654
3655 HasSpaceshipMem hs5, hs6;
3656 if (hs5 < hs6)
3657 return;
3658
3659 HasSpaceshipMem hs7, hs8;
3660 if (hs7 > hs8)
3661 return;
3662
3663 HasSpaceshipMem hs9, hs10;
3664 if (hs9 <= hs10)
3665 return;
3666
3667 HasSpaceshipMem hs11, hs12;
3668 if (hs11 >= hs12)
3669 return;
3670}
3671)cpp";
3672 auto withArgs = [](StringRef lName, StringRef rName) {
3673 return cxxOperatorCallExpr(
3674 hasArgument(0, declRefExpr(to(varDecl(hasName(lName))))),
3675 hasArgument(1, declRefExpr(to(varDecl(hasName(rName))))));
3676 };
3677 {
3678 auto M = ifStmt(hasCondition(cxxOperatorCallExpr(
3679 hasOverloadedOperatorName("=="), withArgs("hs1", "hs2"))));
3680 EXPECT_TRUE(
3681 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3682 EXPECT_TRUE(
3683 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3684 true, {"-std=c++20"}));
3685 }
3686 {
3687 auto M =
3688 unaryOperator(hasOperatorName("!"),
3689 has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="),
3690 withArgs("hs3", "hs4"))));
3691 EXPECT_TRUE(
3692 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3693 EXPECT_FALSE(
3694 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3695 true, {"-std=c++20"}));
3696 }
3697 {
3698 auto M =
3699 unaryOperator(hasOperatorName("!"),
3700 has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="),
3701 withArgs("hs3", "hs4"))));
3702 EXPECT_TRUE(
3703 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3704 EXPECT_FALSE(
3705 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3706 true, {"-std=c++20"}));
3707 }
3708 {
3709 auto M = binaryOperator(
3710 hasOperatorName("<"),
3711 hasLHS(hasDescendant(cxxOperatorCallExpr(
3712 hasOverloadedOperatorName("<=>"), withArgs("hs5", "hs6")))),
3713 hasRHS(integerLiteral(equals(0))));
3714 EXPECT_TRUE(
3715 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3716 EXPECT_FALSE(
3717 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3718 true, {"-std=c++20"}));
3719 }
3720 {
3721 auto M = cxxRewrittenBinaryOperator(withDescendants("hs3", "hs4"));
3722 EXPECT_TRUE(
3723 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3724 EXPECT_TRUE(
3725 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3726 true, {"-std=c++20"}));
3727 }
3728 {
3729 auto M = declRefExpr(to(varDecl(hasName("hs3"))));
3730 EXPECT_TRUE(
3731 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3732 EXPECT_TRUE(
3733 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3734 true, {"-std=c++20"}));
3735 }
3736 {
3737 auto M = cxxRewrittenBinaryOperator(has(
3738 unaryOperator(hasOperatorName("!"), withDescendants("hs3", "hs4"))));
3739 EXPECT_TRUE(
3740 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3741 EXPECT_FALSE(
3742 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3743 true, {"-std=c++20"}));
3744 }
3745 {
3746 auto M = cxxRewrittenBinaryOperator(
3747 has(declRefExpr(to(varDecl(hasName("hs3"))))),
3748 has(declRefExpr(to(varDecl(hasName("hs4"))))));
3749 EXPECT_FALSE(
3750 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3751 EXPECT_TRUE(
3752 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3753 true, {"-std=c++20"}));
3754 }
3755 {
3756 EXPECT_TRUE(matchesConditionally(
3757 Code,
3758 traverse(TK_AsIs,
3759 cxxRewrittenBinaryOperator(
3760 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
3761 isComparisonOperator(),
3762 hasLHS(ignoringImplicit(
3763 declRefExpr(to(varDecl(hasName("hs3")))))),
3764 hasRHS(ignoringImplicit(
3765 declRefExpr(to(varDecl(hasName("hs4")))))),
3766 hasEitherOperand(ignoringImplicit(
3767 declRefExpr(to(varDecl(hasName("hs3")))))),
3768 hasOperands(ignoringImplicit(
3769 declRefExpr(to(varDecl(hasName("hs3"))))),
3770 ignoringImplicit(declRefExpr(
3771 to(varDecl(hasName("hs4")))))))),
3772 true, {"-std=c++20"}));
3773 EXPECT_TRUE(matchesConditionally(
3774 Code,
3775 traverse(TK_IgnoreUnlessSpelledInSource,
3776 cxxRewrittenBinaryOperator(
3777 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
3778 isComparisonOperator(),
3779 hasLHS(declRefExpr(to(varDecl(hasName("hs3"))))),
3780 hasRHS(declRefExpr(to(varDecl(hasName("hs4"))))),
3781 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs3"))))),
3782 hasOperands(declRefExpr(to(varDecl(hasName("hs3")))),
3783 declRefExpr(to(varDecl(hasName("hs4"))))))),
3784 true, {"-std=c++20"}));
3785 }
3786 {
3787 EXPECT_TRUE(matchesConditionally(
3788 Code,
3789 traverse(TK_AsIs,
3790 cxxRewrittenBinaryOperator(
3791 hasOperatorName("<"), hasAnyOperatorName("<", "!="),
3792 isComparisonOperator(),
3793 hasLHS(ignoringImplicit(
3794 declRefExpr(to(varDecl(hasName("hs5")))))),
3795 hasRHS(ignoringImplicit(
3796 declRefExpr(to(varDecl(hasName("hs6")))))),
3797 hasEitherOperand(ignoringImplicit(
3798 declRefExpr(to(varDecl(hasName("hs5")))))),
3799 hasOperands(ignoringImplicit(
3800 declRefExpr(to(varDecl(hasName("hs5"))))),
3801 ignoringImplicit(declRefExpr(
3802 to(varDecl(hasName("hs6")))))))),
3803 true, {"-std=c++20"}));
3804 EXPECT_TRUE(matchesConditionally(
3805 Code,
3806 traverse(TK_IgnoreUnlessSpelledInSource,
3807 cxxRewrittenBinaryOperator(
3808 hasOperatorName("<"), hasAnyOperatorName("<", "!="),
3809 isComparisonOperator(),
3810 hasLHS(declRefExpr(to(varDecl(hasName("hs5"))))),
3811 hasRHS(declRefExpr(to(varDecl(hasName("hs6"))))),
3812 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs5"))))),
3813 hasOperands(declRefExpr(to(varDecl(hasName("hs5")))),
3814 declRefExpr(to(varDecl(hasName("hs6"))))))),
3815 true, {"-std=c++20"}));
3816 }
3817 {
3818 EXPECT_TRUE(matchesConditionally(
3819 Code,
3820 traverse(TK_AsIs,
3821 cxxRewrittenBinaryOperator(
3822 hasOperatorName(">"), hasAnyOperatorName("<", ">"),
3823 isComparisonOperator(),
3824 hasLHS(ignoringImplicit(
3825 declRefExpr(to(varDecl(hasName("hs7")))))),
3826 hasRHS(ignoringImplicit(
3827 declRefExpr(to(varDecl(hasName("hs8")))))),
3828 hasEitherOperand(ignoringImplicit(
3829 declRefExpr(to(varDecl(hasName("hs7")))))),
3830 hasOperands(ignoringImplicit(
3831 declRefExpr(to(varDecl(hasName("hs7"))))),
3832 ignoringImplicit(declRefExpr(
3833 to(varDecl(hasName("hs8")))))))),
3834 true, {"-std=c++20"}));
3835 EXPECT_TRUE(matchesConditionally(
3836 Code,
3837 traverse(TK_IgnoreUnlessSpelledInSource,
3838 cxxRewrittenBinaryOperator(
3839 hasOperatorName(">"), hasAnyOperatorName("<", ">"),
3840 isComparisonOperator(),
3841 hasLHS(declRefExpr(to(varDecl(hasName("hs7"))))),
3842 hasRHS(declRefExpr(to(varDecl(hasName("hs8"))))),
3843 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs7"))))),
3844 hasOperands(declRefExpr(to(varDecl(hasName("hs7")))),
3845 declRefExpr(to(varDecl(hasName("hs8"))))))),
3846 true, {"-std=c++20"}));
3847 }
3848 {
3849 EXPECT_TRUE(matchesConditionally(
3850 Code,
3851 traverse(TK_AsIs,
3852 cxxRewrittenBinaryOperator(
3853 hasOperatorName("<="), hasAnyOperatorName("<", "<="),
3854 isComparisonOperator(),
3855 hasLHS(ignoringImplicit(
3856 declRefExpr(to(varDecl(hasName("hs9")))))),
3857 hasRHS(ignoringImplicit(
3858 declRefExpr(to(varDecl(hasName("hs10")))))),
3859 hasEitherOperand(ignoringImplicit(
3860 declRefExpr(to(varDecl(hasName("hs9")))))),
3861 hasOperands(ignoringImplicit(
3862 declRefExpr(to(varDecl(hasName("hs9"))))),
3863 ignoringImplicit(declRefExpr(
3864 to(varDecl(hasName("hs10")))))))),
3865 true, {"-std=c++20"}));
3866 EXPECT_TRUE(matchesConditionally(
3867 Code,
3868 traverse(TK_IgnoreUnlessSpelledInSource,
3869 cxxRewrittenBinaryOperator(
3870 hasOperatorName("<="), hasAnyOperatorName("<", "<="),
3871 isComparisonOperator(),
3872 hasLHS(declRefExpr(to(varDecl(hasName("hs9"))))),
3873 hasRHS(declRefExpr(to(varDecl(hasName("hs10"))))),
3874 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs9"))))),
3875 hasOperands(declRefExpr(to(varDecl(hasName("hs9")))),
3876 declRefExpr(to(varDecl(hasName("hs10"))))))),
3877 true, {"-std=c++20"}));
3878 }
3879 {
3880 EXPECT_TRUE(matchesConditionally(
3881 Code,
3882 traverse(TK_AsIs,
3883 cxxRewrittenBinaryOperator(
3884 hasOperatorName(">="), hasAnyOperatorName("<", ">="),
3885 isComparisonOperator(),
3886 hasLHS(ignoringImplicit(
3887 declRefExpr(to(varDecl(hasName("hs11")))))),
3888 hasRHS(ignoringImplicit(
3889 declRefExpr(to(varDecl(hasName("hs12")))))),
3890 hasEitherOperand(ignoringImplicit(
3891 declRefExpr(to(varDecl(hasName("hs11")))))),
3892 hasOperands(ignoringImplicit(
3893 declRefExpr(to(varDecl(hasName("hs11"))))),
3894 ignoringImplicit(declRefExpr(
3895 to(varDecl(hasName("hs12")))))))),
3896 true, {"-std=c++20"}));
3897 EXPECT_TRUE(matchesConditionally(
3898 Code,
3899 traverse(
3900 TK_IgnoreUnlessSpelledInSource,
3901 cxxRewrittenBinaryOperator(
3902 hasOperatorName(">="), hasAnyOperatorName("<", ">="),
3903 isComparisonOperator(),
3904 hasLHS(declRefExpr(to(varDecl(hasName("hs11"))))),
3905 hasRHS(declRefExpr(to(varDecl(hasName("hs12"))))),
3906 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs11"))))),
3907 hasOperands(declRefExpr(to(varDecl(hasName("hs11")))),
3908 declRefExpr(to(varDecl(hasName("hs12"))))))),
3909 true, {"-std=c++20"}));
3910 }
3911
3912 Code = R"cpp(
3913struct S {};
3914
3915struct HasOpEq
3916{
3917 bool operator==(const S& other) const
3918 {
3919 return true;
3920 }
3921};
3922
3923struct HasOpEqMem {
3924 bool operator==(const HasOpEqMem&) const { return true; }
3925};
3926
3927struct HasOpEqFree {
3928};
3929bool operator==(const HasOpEqFree&, const HasOpEqFree&) { return true; }
3930
3931void binop()
3932{
3933 {
3934 HasOpEq s1;
3935 S s2;
3936 if (s1 != s2)
3937 return;
3938 }
3939
3940 {
3941 int i1;
3942 int i2;
3943 if (i1 != i2)
3944 return;
3945 }
3946
3947 {
3948 HasOpEqMem M1;
3949 HasOpEqMem M2;
3950 if (M1 == M2)
3951 return;
3952 }
3953
3954 {
3955 HasOpEqFree F1;
3956 HasOpEqFree F2;
3957 if (F1 == F2)
3958 return;
3959 }
3960}
3961)cpp";
3962 {
3963 EXPECT_TRUE(matchesConditionally(
3964 Code,
3965 traverse(TK_AsIs,
3966 binaryOperation(
3967 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
3968 isComparisonOperator(),
3969 hasLHS(ignoringImplicit(
3970 declRefExpr(to(varDecl(hasName("s1")))))),
3971 hasRHS(ignoringImplicit(
3972 declRefExpr(to(varDecl(hasName("s2")))))),
3973 hasEitherOperand(ignoringImplicit(
3974 declRefExpr(to(varDecl(hasName("s2")))))),
3975 hasOperands(ignoringImplicit(
3976 declRefExpr(to(varDecl(hasName("s1"))))),
3977 ignoringImplicit(declRefExpr(
3978 to(varDecl(hasName("s2")))))))),
3979 true, {"-std=c++20"}));
3980 EXPECT_TRUE(matchesConditionally(
3981 Code,
3982 traverse(TK_AsIs, binaryOperation(hasOperatorName("!="),
3983 hasLHS(ignoringImplicit(declRefExpr(
3984 to(varDecl(hasName("i1")))))),
3985 hasRHS(ignoringImplicit(declRefExpr(
3986 to(varDecl(hasName("i2")))))))),
3987 true, {"-std=c++20"}));
3988 EXPECT_TRUE(matchesConditionally(
3989 Code,
3990 traverse(TK_AsIs, binaryOperation(hasOperatorName("=="),
3991 hasLHS(ignoringImplicit(declRefExpr(
3992 to(varDecl(hasName("M1")))))),
3993 hasRHS(ignoringImplicit(declRefExpr(
3994 to(varDecl(hasName("M2")))))))),
3995 true, {"-std=c++20"}));
3996 EXPECT_TRUE(matchesConditionally(
3997 Code,
3998 traverse(TK_AsIs, binaryOperation(hasOperatorName("=="),
3999 hasLHS(ignoringImplicit(declRefExpr(
4000 to(varDecl(hasName("F1")))))),
4001 hasRHS(ignoringImplicit(declRefExpr(
4002 to(varDecl(hasName("F2")))))))),
4003 true, {"-std=c++20"}));
4004 EXPECT_TRUE(matchesConditionally(
4005 Code,
4006 traverse(TK_IgnoreUnlessSpelledInSource,
4007 binaryOperation(
4008 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4009 isComparisonOperator(),
4010 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
4011 hasRHS(declRefExpr(to(varDecl(hasName("s2"))))),
4012 hasEitherOperand(declRefExpr(to(varDecl(hasName("s2"))))),
4013 hasOperands(declRefExpr(to(varDecl(hasName("s1")))),
4014 declRefExpr(to(varDecl(hasName("s2"))))))),
4015 true, {"-std=c++20"}));
4016 EXPECT_TRUE(matchesConditionally(
4017 Code,
4018 traverse(
4019 TK_IgnoreUnlessSpelledInSource,
4020 binaryOperation(hasOperatorName("!="),
4021 hasLHS(declRefExpr(to(varDecl(hasName("i1"))))),
4022 hasRHS(declRefExpr(to(varDecl(hasName("i2"))))))),
4023 true, {"-std=c++20"}));
4024 EXPECT_TRUE(matchesConditionally(
4025 Code,
4026 traverse(
4027 TK_IgnoreUnlessSpelledInSource,
4028 binaryOperation(hasOperatorName("=="),
4029 hasLHS(declRefExpr(to(varDecl(hasName("M1"))))),
4030 hasRHS(declRefExpr(to(varDecl(hasName("M2"))))))),
4031 true, {"-std=c++20"}));
4032 EXPECT_TRUE(matchesConditionally(
4033 Code,
4034 traverse(
4035 TK_IgnoreUnlessSpelledInSource,
4036 binaryOperation(hasOperatorName("=="),
4037 hasLHS(declRefExpr(to(varDecl(hasName("F1"))))),
4038 hasRHS(declRefExpr(to(varDecl(hasName("F2"))))))),
4039 true, {"-std=c++20"}));
4040 }
4041}
4042
4043TEST(IgnoringImpCasts, PathologicalLambda) {
4044
4045 // Test that deeply nested lambdas are not a performance penalty
4046 StringRef Code = R"cpp(
4047void f() {
4048 [] {
4049 [] {
4050 [] {
4051 [] {
4052 [] {
4053 [] {
4054 [] {
4055 [] {
4056 [] {
4057 [] {
4058 [] {
4059 [] {
4060 [] {
4061 [] {
4062 [] {
4063 [] {
4064 [] {
4065 [] {
4066 [] {
4067 [] {
4068 [] {
4069 [] {
4070 [] {
4071 [] {
4072 [] {
4073 [] {
4074 [] {
4075 [] {
4076 [] {
4077 int i = 42;
4078 (void)i;
4079 }();
4080 }();
4081 }();
4082 }();
4083 }();
4084 }();
4085 }();
4086 }();
4087 }();
4088 }();
4089 }();
4090 }();
4091 }();
4092 }();
4093 }();
4094 }();
4095 }();
4096 }();
4097 }();
4098 }();
4099 }();
4100 }();
4101 }();
4102 }();
4103 }();
4104 }();
4105 }();
4106 }();
4107 }();
4108}
4109 )cpp";
4110
4111 EXPECT_TRUE(matches(Code, integerLiteral(equals(42))));
4112 EXPECT_TRUE(matches(Code, functionDecl(hasDescendant(integerLiteral(equals(42))))));
4113}
4114
4115TEST(IgnoringImpCasts, MatchesImpCasts) {
4116 // This test checks that ignoringImpCasts matches when implicit casts are
4117 // present and its inner matcher alone does not match.
4118 // Note that this test creates an implicit const cast.
4119 EXPECT_TRUE(matches("int x = 0; const int y = x;",
4120 varDecl(hasInitializer(ignoringImpCasts(
4121 declRefExpr(to(varDecl(hasName("x")))))))));
4122 // This test creates an implict cast from int to char.
4123 EXPECT_TRUE(matches("char x = 0;",
4124 varDecl(hasInitializer(ignoringImpCasts(
4125 integerLiteral(equals(0)))))));
4126}
4127
4128TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
4129 // These tests verify that ignoringImpCasts does not match if the inner
4130 // matcher does not match.
4131 // Note that the first test creates an implicit const cast.
4132 EXPECT_TRUE(notMatches("int x; const int y = x;",
4133 varDecl(hasInitializer(ignoringImpCasts(
4134 unless(anything()))))));
4135 EXPECT_TRUE(notMatches("int x; int y = x;",
4136 varDecl(hasInitializer(ignoringImpCasts(
4137 unless(anything()))))));
4138
4139 // These tests verify that ignoringImplictCasts does not look through explicit
4140 // casts or parentheses.
4141 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
4142 varDecl(hasInitializer(ignoringImpCasts(
4143 integerLiteral())))));
4144 EXPECT_TRUE(notMatches(
4145 "int i = (0);",
4146 traverse(TK_AsIs,
4147 varDecl(hasInitializer(ignoringImpCasts(integerLiteral()))))));
4148 EXPECT_TRUE(notMatches("float i = (float)0;",
4149 varDecl(hasInitializer(ignoringImpCasts(
4150 integerLiteral())))));
4151 EXPECT_TRUE(notMatches("float i = float(0);",
4152 varDecl(hasInitializer(ignoringImpCasts(
4153 integerLiteral())))));
4154}
4155
4156TEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
4157 // This test verifies that expressions that do not have implicit casts
4158 // still match the inner matcher.
4159 EXPECT_TRUE(matches("int x = 0; int &y = x;",
4160 varDecl(hasInitializer(ignoringImpCasts(
4161 declRefExpr(to(varDecl(hasName("x")))))))));
4162}
4163
4164TEST(IgnoringParenCasts, MatchesParenCasts) {
4165 // This test checks that ignoringParenCasts matches when parentheses and/or
4166 // casts are present and its inner matcher alone does not match.
4167 EXPECT_TRUE(matches("int x = (0);",
4168 varDecl(hasInitializer(ignoringParenCasts(
4169 integerLiteral(equals(0)))))));
4170 EXPECT_TRUE(matches("int x = (((((0)))));",
4171 varDecl(hasInitializer(ignoringParenCasts(
4172 integerLiteral(equals(0)))))));
4173
4174 // This test creates an implict cast from int to char in addition to the
4175 // parentheses.
4176 EXPECT_TRUE(matches("char x = (0);",
4177 varDecl(hasInitializer(ignoringParenCasts(
4178 integerLiteral(equals(0)))))));
4179
4180 EXPECT_TRUE(matches("char x = (char)0;",
4181 varDecl(hasInitializer(ignoringParenCasts(
4182 integerLiteral(equals(0)))))));
4183 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
4184 varDecl(hasInitializer(ignoringParenCasts(
4185 integerLiteral(equals(0)))))));
4186}
4187
4188TEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
4189 // This test verifies that expressions that do not have any casts still match.
4190 EXPECT_TRUE(matches("int x = 0;",
4191 varDecl(hasInitializer(ignoringParenCasts(
4192 integerLiteral(equals(0)))))));
4193}
4194
4195TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
4196 // These tests verify that ignoringImpCasts does not match if the inner
4197 // matcher does not match.
4198 EXPECT_TRUE(notMatches("int x = ((0));",
4199 varDecl(hasInitializer(ignoringParenCasts(
4200 unless(anything()))))));
4201
4202 // This test creates an implicit cast from int to char in addition to the
4203 // parentheses.
4204 EXPECT_TRUE(notMatches("char x = ((0));",
4205 varDecl(hasInitializer(ignoringParenCasts(
4206 unless(anything()))))));
4207
4208 EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
4209 varDecl(hasInitializer(ignoringParenCasts(
4210 unless(anything()))))));
4211}
4212
4213TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
4214 // This test checks that ignoringParenAndImpCasts matches when
4215 // parentheses and/or implicit casts are present and its inner matcher alone
4216 // does not match.
4217 // Note that this test creates an implicit const cast.
4218 EXPECT_TRUE(matches("int x = 0; const int y = x;",
4219 varDecl(hasInitializer(ignoringParenImpCasts(
4220 declRefExpr(to(varDecl(hasName("x")))))))));
4221 // This test creates an implicit cast from int to char.
4222 EXPECT_TRUE(matches("const char x = (0);",
4223 varDecl(hasInitializer(ignoringParenImpCasts(
4224 integerLiteral(equals(0)))))));
4225}
4226
4227TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
4228 // This test verifies that expressions that do not have parentheses or
4229 // implicit casts still match.
4230 EXPECT_TRUE(matches("int x = 0; int &y = x;",
4231 varDecl(hasInitializer(ignoringParenImpCasts(
4232 declRefExpr(to(varDecl(hasName("x")))))))));
4233 EXPECT_TRUE(matches("int x = 0;",
4234 varDecl(hasInitializer(ignoringParenImpCasts(
4235 integerLiteral(equals(0)))))));
4236}
4237
4238TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
4239 // These tests verify that ignoringParenImpCasts does not match if
4240 // the inner matcher does not match.
4241 // This test creates an implicit cast.
4242 EXPECT_TRUE(notMatches("char c = ((3));",
4243 varDecl(hasInitializer(ignoringParenImpCasts(
4244 unless(anything()))))));
4245 // These tests verify that ignoringParenAndImplictCasts does not look
4246 // through explicit casts.
4247 EXPECT_TRUE(notMatches("float y = (float(0));",
4248 varDecl(hasInitializer(ignoringParenImpCasts(
4249 integerLiteral())))));
4250 EXPECT_TRUE(notMatches("float y = (float)0;",
4251 varDecl(hasInitializer(ignoringParenImpCasts(
4252 integerLiteral())))));
4253 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
4254 varDecl(hasInitializer(ignoringParenImpCasts(
4255 integerLiteral())))));
4256}
4257
4258TEST(HasSourceExpression, MatchesImplicitCasts) {
4259 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
4260 "void r() {string a_string; URL url = a_string; }",
4261 traverse(TK_AsIs, implicitCastExpr(hasSourceExpression(
4262 cxxConstructExpr())))));
4263}
4264
4265TEST(HasSourceExpression, MatchesExplicitCasts) {
4266 EXPECT_TRUE(
4267 matches("float x = static_cast<float>(42);",
4268 traverse(TK_AsIs, explicitCastExpr(hasSourceExpression(
4269 hasDescendant(expr(integerLiteral())))))));
4270}
4271
4272TEST(UsingDeclaration, MatchesSpecificTarget) {
4273 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
4274 usingDecl(hasAnyUsingShadowDecl(
4275 hasTargetDecl(functionDecl())))));
4276 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
4277 usingDecl(hasAnyUsingShadowDecl(
4278 hasTargetDecl(functionDecl())))));
4279}
4280
4281TEST(UsingDeclaration, ThroughUsingDeclaration) {
4282 EXPECT_TRUE(matches(
4283 "namespace a { void f(); } using a::f; void g() { f(); }",
4284 declRefExpr(throughUsingDecl(anything()))));
4285 EXPECT_TRUE(notMatches(
4286 "namespace a { void f(); } using a::f; void g() { a::f(); }",
4287 declRefExpr(throughUsingDecl(anything()))));
4288}
4289
4290TEST(SingleDecl, IsSingleDecl) {
4291 StatementMatcher SingleDeclStmt =
4292 declStmt(hasSingleDecl(varDecl(hasInitializer(anything()))));
4293 EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
4294 EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
4295 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
4296 SingleDeclStmt));
4297}
4298
4299TEST(DeclStmt, ContainsDeclaration) {
4300 DeclarationMatcher MatchesInit = varDecl(hasInitializer(anything()));
4301
4302 EXPECT_TRUE(matches("void f() {int a = 4;}",
4303 declStmt(containsDeclaration(0, MatchesInit))));
4304 EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
4305 declStmt(containsDeclaration(0, MatchesInit),
4306 containsDeclaration(1, MatchesInit))));
4307 unsigned WrongIndex = 42;
4308 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
4309 declStmt(containsDeclaration(WrongIndex,
4310 MatchesInit))));
4311}
4312
4313TEST(SwitchCase, MatchesEachCase) {
4314 EXPECT_TRUE(notMatches("void x() { switch(42); }",
4315 switchStmt(forEachSwitchCase(caseStmt()))));
4316 EXPECT_TRUE(matches("void x() { switch(42) case 42:; }",
4317 switchStmt(forEachSwitchCase(caseStmt()))));
4318 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }",
4319 switchStmt(forEachSwitchCase(caseStmt()))));
4320 EXPECT_TRUE(notMatches(
4321 "void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }",
4322 ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt()))))));
4323 EXPECT_TRUE(matches(
4324 "void x() { switch(42) { case 1+1: case 4:; } }",
4325 traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
4326 constantExpr(has(integerLiteral())))))))));
4327 EXPECT_TRUE(notMatches(
4328 "void x() { switch(42) { case 1+1: case 2+2:; } }",
4329 traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
4330 constantExpr(has(integerLiteral())))))))));
4331 EXPECT_TRUE(notMatches(
4332 "void x() { switch(42) { case 1 ... 2:; } }",
4333 traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
4334 constantExpr(has(integerLiteral())))))))));
4335 EXPECT_TRUE(matchAndVerifyResultTrue(
4336 "void x() { switch (42) { case 1: case 2: case 3: default:; } }",
4337 switchStmt(forEachSwitchCase(caseStmt().bind("x"))),
4338 std::make_unique<VerifyIdIsBoundTo<CaseStmt>>("x", 3)));
4339}
4340
4341TEST(Declaration, HasExplicitSpecifier) {
4342
4343 EXPECT_TRUE(notMatches("void f();",
4344 functionDecl(hasExplicitSpecifier(constantExpr())),
4345 langCxx20OrLater()));
4346 EXPECT_TRUE(
4347 notMatches("template<bool b> struct S { explicit operator int(); };",
4348 cxxConversionDecl(
4349 hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
4350 langCxx20OrLater()));
4351 EXPECT_TRUE(
4352 notMatches("template<bool b> struct S { explicit(b) operator int(); };",
4353 cxxConversionDecl(
4354 hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
4355 langCxx20OrLater()));
4356 EXPECT_TRUE(
4357 matches("struct S { explicit(true) operator int(); };",
4358 traverse(TK_AsIs, cxxConversionDecl(hasExplicitSpecifier(
4359 constantExpr(has(cxxBoolLiteral()))))),
4360 langCxx20OrLater()));
4361 EXPECT_TRUE(
4362 matches("struct S { explicit(false) operator int(); };",
4363 traverse(TK_AsIs, cxxConversionDecl(hasExplicitSpecifier(
4364 constantExpr(has(cxxBoolLiteral()))))),
4365 langCxx20OrLater()));
4366 EXPECT_TRUE(
4367 notMatches("template<bool b> struct S { explicit(b) S(int); };",
4368 traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier(
4369 constantExpr(has(cxxBoolLiteral()))))),
4370 langCxx20OrLater()));
4371 EXPECT_TRUE(
4372 matches("struct S { explicit(true) S(int); };",
4373 traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier(
4374 constantExpr(has(cxxBoolLiteral()))))),
4375 langCxx20OrLater()));
4376 EXPECT_TRUE(
4377 matches("struct S { explicit(false) S(int); };",
4378 traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier(
4379 constantExpr(has(cxxBoolLiteral()))))),
4380 langCxx20OrLater()));
4381 EXPECT_TRUE(
4382 notMatches("template<typename T> struct S { S(int); };"
4383 "template<bool b = true> explicit(b) S(int) -> S<int>;",
4384 traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier(
4385 constantExpr(has(cxxBoolLiteral()))))),
4386 langCxx20OrLater()));
4387 EXPECT_TRUE(
4388 matches("template<typename T> struct S { S(int); };"
4389 "explicit(true) S(int) -> S<int>;",
4390 traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier(
4391 constantExpr(has(cxxBoolLiteral()))))),
4392 langCxx20OrLater()));
4393 EXPECT_TRUE(
4394 matches("template<typename T> struct S { S(int); };"
4395 "explicit(false) S(int) -> S<int>;",
4396 traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier(
4397 constantExpr(has(cxxBoolLiteral()))))),
4398 langCxx20OrLater()));
4399}
4400
4401TEST(ForEachConstructorInitializer, MatchesInitializers) {
4402 EXPECT_TRUE(matches(
4403 "struct X { X() : i(42), j(42) {} int i, j; };",
4404 cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer()))));
4405}
4406
4407TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
4408 EXPECT_TRUE(notMatches(
4409 "void x() { if(true) {} }",
4410 ifStmt(hasConditionVariableStatement(declStmt()))));
4411 EXPECT_TRUE(notMatches(
4412 "void x() { int x; if((x = 42)) {} }",
4413 ifStmt(hasConditionVariableStatement(declStmt()))));
4414}
4415
4416TEST(HasConditionVariableStatement, MatchesConditionVariables) {
4417 EXPECT_TRUE(matches(
4418 "void x() { if(int* a = 0) {} }",
4419 ifStmt(hasConditionVariableStatement(declStmt()))));
4420}
4421
4422TEST(ForEach, BindsOneNode) {
4423 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
4424 recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))),
4425 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("x", 1)));
4426}
4427
4428TEST(ForEach, BindsMultipleNodes) {
4429 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
4430 recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))),
4431 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 3)));
4432}
4433
4434TEST(ForEach, BindsRecursiveCombinations) {
4435 EXPECT_TRUE(matchAndVerifyResultTrue(
4436 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
4437 recordDecl(hasName("C"),
4438 forEach(recordDecl(forEach(fieldDecl().bind("f"))))),
4439 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 4)));
4440}
4441
4442TEST(ForEach, DoesNotIgnoreImplicit) {
4443 StringRef Code = R"cpp(
4444void foo()
4445{
4446 int i = 0;
4447 int b = 4;
4448 i < b;
4449}
4450)cpp";
4451 EXPECT_TRUE(matchAndVerifyResultFalse(
4452 Code, binaryOperator(forEach(declRefExpr().bind("dre"))),
4453 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 0)));
4454
4455 EXPECT_TRUE(matchAndVerifyResultTrue(
4456 Code,
4457 binaryOperator(forEach(
4458 implicitCastExpr(hasSourceExpression(declRefExpr().bind("dre"))))),
4459 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2)));
4460
4461 EXPECT_TRUE(matchAndVerifyResultTrue(
4462 Code,
4463 binaryOperator(
4464 forEach(expr(ignoringImplicit(declRefExpr().bind("dre"))))),
4465 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2)));
4466
4467 EXPECT_TRUE(matchAndVerifyResultTrue(
4468 Code,
4469 traverse(TK_IgnoreUnlessSpelledInSource,
4470 binaryOperator(forEach(declRefExpr().bind("dre")))),
4471 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2)));
4472}
4473
4474TEST(ForEachDescendant, BindsOneNode) {
4475 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
4476 recordDecl(hasName("C"),
4477 forEachDescendant(fieldDecl(hasName("x")).bind("x"))),
4478 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("x", 1)));
4479}
4480
4481TEST(ForEachDescendant, NestedForEachDescendant) {
4482 DeclarationMatcher m = recordDecl(
4483 isDefinition(), decl().bind("x"), hasName("C"));
4484 EXPECT_TRUE(matchAndVerifyResultTrue(
4485 "class A { class B { class C {}; }; };",
4486 recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))),
4487 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", "C")));
4488
4489 // Check that a partial match of 'm' that binds 'x' in the
4490 // first part of anyOf(m, anything()) will not overwrite the
4491 // binding created by the earlier binding in the hasDescendant.
4492 EXPECT_TRUE(matchAndVerifyResultTrue(
4493 "class A { class B { class C {}; }; };",
4494 recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))),
4495 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", "C")));
4496}
4497
4498TEST(ForEachDescendant, BindsMultipleNodes) {
4499 EXPECT_TRUE(matchAndVerifyResultTrue(
4500 "class C { class D { int x; int y; }; "
4501 " class E { class F { int y; int z; }; }; };",
4502 recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))),
4503 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 4)));
4504}
4505
4506TEST(ForEachDescendant, BindsRecursiveCombinations) {
4507 EXPECT_TRUE(matchAndVerifyResultTrue(
4508 "class C { class D { "
4509 " class E { class F { class G { int y; int z; }; }; }; }; };",
4510 recordDecl(hasName("C"), forEachDescendant(recordDecl(
4511 forEachDescendant(fieldDecl().bind("f"))))),
4512 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 8)));
4513}
4514
4515TEST(ForEachDescendant, BindsCombinations) {
4516 EXPECT_TRUE(matchAndVerifyResultTrue(
4517 "void f() { if(true) {} if (true) {} while (true) {} if (true) {} while "
4518 "(true) {} }",
4519 compoundStmt(forEachDescendant(ifStmt().bind("if")),
4520 forEachDescendant(whileStmt().bind("while"))),
4521 std::make_unique<VerifyIdIsBoundTo<IfStmt>>("if", 6)));
4522}
4523
4524TEST(Has, DoesNotDeleteBindings) {
4525 EXPECT_TRUE(matchAndVerifyResultTrue(
4526 "class X { int a; };", recordDecl(decl().bind("x"), has(fieldDecl())),
4527 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
4528}
4529
4530TEST(TemplateArgumentLoc, Matches) {
4531 EXPECT_TRUE(matchAndVerifyResultTrue(
4532 R"cpp(
4533 template <typename A, int B, template <typename> class C> class X {};
4534 class A {};
4535 const int B = 42;
4536 template <typename> class C {};
4537 X<A, B, C> x;
4538 )cpp",
4539 templateArgumentLoc().bind("x"),
4540 std::make_unique<VerifyIdIsBoundTo<TemplateArgumentLoc>>("x", 3)));
4541}
4542
4543TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
4544 // Those matchers cover all the cases where an inner matcher is called
4545 // and there is not a 1:1 relationship between the match of the outer
4546 // matcher and the match of the inner matcher.
4547 // The pattern to look for is:
4548 // ... return InnerMatcher.matches(...); ...
4549 // In which case no special handling is needed.
4550 //
4551 // On the other hand, if there are multiple alternative matches
4552 // (for example forEach*) or matches might be discarded (for example has*)
4553 // the implementation must make sure that the discarded matches do not
4554 // affect the bindings.
4555 // When new such matchers are added, add a test here that:
4556 // - matches a simple node, and binds it as the first thing in the matcher:
4557 // recordDecl(decl().bind("x"), hasName("X")))
4558 // - uses the matcher under test afterwards in a way that not the first
4559 // alternative is matched; for anyOf, that means the first branch
4560 // would need to return false; for hasAncestor, it means that not
4561 // the direct parent matches the inner matcher.
4562
4563 EXPECT_TRUE(matchAndVerifyResultTrue(
4564 "class X { int y; };",
4565 recordDecl(
4566 recordDecl().bind("x"), hasName("::X"),
4567 anyOf(forEachDescendant(recordDecl(hasName("Y"))), anything())),
4568 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x", 1)));
4569 EXPECT_TRUE(matchAndVerifyResultTrue(
4570 "class X {};", recordDecl(recordDecl().bind("x"), hasName("::X"),
4571 anyOf(unless(anything()), anything())),
4572 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x", 1)));
4573 EXPECT_TRUE(matchAndVerifyResultTrue(
4574 "template<typename T1, typename T2> class X {}; X<float, int> x;",
4575 classTemplateSpecializationDecl(
4576 decl().bind("x"),
4577 hasAnyTemplateArgument(refersToType(asString("int")))),
4578 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
4579 EXPECT_TRUE(matchAndVerifyResultTrue(
4580 "class X { void f(); void g(); };",
4581 cxxRecordDecl(decl().bind("x"), hasMethod(hasName("g"))),
4582 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
4583 EXPECT_TRUE(matchAndVerifyResultTrue(
4584 "class X { X() : a(1), b(2) {} double a; int b; };",
4585 recordDecl(decl().bind("x"),
4586 has(cxxConstructorDecl(
4587 hasAnyConstructorInitializer(forField(hasName("b")))))),
4588 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
4589 EXPECT_TRUE(matchAndVerifyResultTrue(
4590 "void x(int, int) { x(0, 42); }",
4591 callExpr(expr().bind("x"), hasAnyArgument(integerLiteral(equals(42)))),
4592 std::make_unique<VerifyIdIsBoundTo<Expr>>("x", 1)));
4593 EXPECT_TRUE(matchAndVerifyResultTrue(
4594 "void x(int, int y) {}",
4595 functionDecl(decl().bind("x"), hasAnyParameter(hasName("y"))),
4596 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
4597 EXPECT_TRUE(matchAndVerifyResultTrue(
4598 "void x() { return; if (true) {} }",
4599 functionDecl(decl().bind("x"),
4600 has(compoundStmt(hasAnySubstatement(ifStmt())))),
4601 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
4602 EXPECT_TRUE(matchAndVerifyResultTrue(
4603 "namespace X { void b(int); void b(); }"
4604 "using X::b;",
4605 usingDecl(decl().bind("x"), hasAnyUsingShadowDecl(hasTargetDecl(
4606 functionDecl(parameterCountIs(1))))),
4607 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
4608 EXPECT_TRUE(matchAndVerifyResultTrue(
4609 "class A{}; class B{}; class C : B, A {};",
4610 cxxRecordDecl(decl().bind("x"), isDerivedFrom("::A")),
4611 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
4612 EXPECT_TRUE(matchAndVerifyResultTrue(
4613 "class A{}; typedef A B; typedef A C; typedef A D;"
4614 "class E : A {};",
4615 cxxRecordDecl(decl().bind("x"), isDerivedFrom("C")),
4616 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
4617 EXPECT_TRUE(matchAndVerifyResultTrue(
4618 "class A { class B { void f() {} }; };",
4619 functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
4620 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
4621 EXPECT_TRUE(matchAndVerifyResultTrue(
4622 "template <typename T> struct A { struct B {"
4623 " void f() { if(true) {} }"
4624 "}; };"
4625 "void t() { A<int>::B b; b.f(); }",
4626 ifStmt(stmt().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
4627 std::make_unique<VerifyIdIsBoundTo<Stmt>>("x", 2)));
4628 EXPECT_TRUE(matchAndVerifyResultTrue(
4629 "class A {};",
4630 recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))),
4631 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
4632 EXPECT_TRUE(matchAndVerifyResultTrue(
4633 "class A { A() : s(), i(42) {} const char *s; int i; };",
4634 cxxConstructorDecl(hasName("::A::A"), decl().bind("x"),
4635 forEachConstructorInitializer(forField(hasName("i")))),
4636 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
4637}
4638
4639TEST(ForEachDescendant, BindsCorrectNodes) {
4640 EXPECT_TRUE(matchAndVerifyResultTrue(
4641 "class C { void f(); int i; };",
4642 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
4643 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("decl", 1)));
4644 EXPECT_TRUE(matchAndVerifyResultTrue(
4645 "class C { void f() {} int i; };",
4646 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
4647 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("decl", 1)));
4648}
4649
4650TEST(FindAll, BindsNodeOnMatch) {
4651 EXPECT_TRUE(matchAndVerifyResultTrue(
4652 "class A {};",
4653 recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))),
4654 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("v", 1)));
4655}
4656
4657TEST(FindAll, BindsDescendantNodeOnMatch) {
4658 EXPECT_TRUE(matchAndVerifyResultTrue(
4659 "class A { int a; int b; };",
4660 recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))),
4661 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 2)));
4662}
4663
4664TEST(FindAll, BindsNodeAndDescendantNodesOnOneMatch) {
4665 EXPECT_TRUE(matchAndVerifyResultTrue(
4666 "class A { int a; int b; };",
4667 recordDecl(hasName("::A"),
4668 findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"),
4669 fieldDecl().bind("v"))))),
4670 std::make_unique<VerifyIdIsBoundTo<Decl>>("v", 3)));
4671
4672 EXPECT_TRUE(matchAndVerifyResultTrue(
4673 "class A { class B {}; class C {}; };",
4674 recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))),
4675 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("v", 3)));
4676}
4677
4678TEST(HasAncenstor, MatchesDeclarationAncestors) {
4679 EXPECT_TRUE(matches(
4680 "class A { class B { class C {}; }; };",
4681 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A"))))));
4682}
4683
4684TEST(HasAncenstor, FailsIfNoAncestorMatches) {
4685 EXPECT_TRUE(notMatches(
4686 "class A { class B { class C {}; }; };",
4687 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X"))))));
4688}
4689
4690TEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) {
4691 EXPECT_TRUE(matches(
4692 "class A { class B { void f() { C c; } class C {}; }; };",
4693 varDecl(hasName("c"), hasType(recordDecl(hasName("C"),
4694 hasAncestor(recordDecl(hasName("A"))))))));
4695}
4696
4697TEST(HasAncenstor, MatchesStatementAncestors) {
4698 EXPECT_TRUE(matches(
4699 "void f() { if (true) { while (false) { 42; } } }",
4700 integerLiteral(equals(42), hasAncestor(ifStmt()))));
4701}
4702
4703TEST(HasAncestor, DrillsThroughDifferentHierarchies) {
4704 EXPECT_TRUE(matches(
4705 "void f() { if (true) { int x = 42; } }",
4706 integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f"))))));
4707}
4708
4709TEST(HasAncestor, BindsRecursiveCombinations) {
4710 EXPECT_TRUE(matchAndVerifyResultTrue(
4711 "class C { class D { class E { class F { int y; }; }; }; };",
4712 fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))),
4713 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("r", 1)));
4714}
4715
4716TEST(HasAncestor, BindsCombinationsWithHasDescendant) {
4717 EXPECT_TRUE(matchAndVerifyResultTrue(
4718 "class C { class D { class E { class F { int y; }; }; }; };",
4719 fieldDecl(hasAncestor(
4720 decl(
4721 hasDescendant(recordDecl(isDefinition(),
4722 hasAncestor(recordDecl())))
4723 ).bind("d")
4724 )),
4725 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("d", "E")));
4726}
4727
4728TEST(HasAncestor, MatchesClosestAncestor) {
4729 EXPECT_TRUE(matchAndVerifyResultTrue(
4730 "template <typename T> struct C {"
4731 " void f(int) {"
4732 " struct I { void g(T) { int x; } } i; i.g(42);"
4733 " }"
4734 "};"
4735 "template struct C<int>;",
4736 varDecl(hasName("x"),
4737 hasAncestor(functionDecl(hasParameter(
4738 0, varDecl(hasType(asString("int"))))).bind("f"))).bind("v"),
4739 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("f", "g", 2)));
4740}
4741
4742TEST(HasAncestor, MatchesInTemplateInstantiations) {
4743 EXPECT_TRUE(matches(
4744 "template <typename T> struct A { struct B { struct C { T t; }; }; }; "
4745 "A<int>::B::C a;",
4746 fieldDecl(hasType(asString("int")),
4747 hasAncestor(recordDecl(hasName("A"))))));
4748}
4749
4750TEST(HasAncestor, MatchesInImplicitCode) {
4751 EXPECT_TRUE(matches(
4752 "struct X {}; struct A { A() {} X x; };",
4753 cxxConstructorDecl(
4754 hasAnyConstructorInitializer(withInitializer(expr(
4755 hasAncestor(recordDecl(hasName("A")))))))));
4756}
4757
4758TEST(HasParent, MatchesOnlyParent) {
4759 EXPECT_TRUE(matches(
4760 "void f() { if (true) { int x = 42; } }",
4761 compoundStmt(hasParent(ifStmt()))));
4762 EXPECT_TRUE(notMatches(
4763 "void f() { for (;;) { int x = 42; } }",
4764 compoundStmt(hasParent(ifStmt()))));
4765 EXPECT_TRUE(notMatches(
4766 "void f() { if (true) for (;;) { int x = 42; } }",
4767 compoundStmt(hasParent(ifStmt()))));
4768}
4769
4770TEST(MatcherMemoize, HasParentDiffersFromHas) {
4771 // Test introduced after detecting a bug in memoization
4772 constexpr auto code = "void f() { throw 1; }";
4773 EXPECT_TRUE(notMatches(
4774 code,
4775 cxxThrowExpr(hasParent(expr()))));
4776 EXPECT_TRUE(matches(
4777 code,
4778 cxxThrowExpr(has(expr()))));
4779 EXPECT_TRUE(matches(
4780 code,
4781 cxxThrowExpr(anyOf(hasParent(expr()), has(expr())))));
4782}
4783
4784TEST(MatcherMemoize, HasDiffersFromHasDescendant) {
4785 // Test introduced after detecting a bug in memoization
4786 constexpr auto code = "void f() { throw 1+1; }";
4787 EXPECT_TRUE(notMatches(
4788 code,
4789 cxxThrowExpr(has(integerLiteral()))));
4790 EXPECT_TRUE(matches(
4791 code,
4792 cxxThrowExpr(hasDescendant(integerLiteral()))));
4793 EXPECT_TRUE(
4794 notMatches(code, cxxThrowExpr(allOf(hasDescendant(integerLiteral()),
4795 has(integerLiteral())))));
4796}
4797TEST(HasAncestor, MatchesAllAncestors) {
4798 EXPECT_TRUE(matches(
4799 "template <typename T> struct C { static void f() { 42; } };"
4800 "void t() { C<int>::f(); }",
4801 integerLiteral(
4802 equals(42),
4803 allOf(
4804 hasAncestor(cxxRecordDecl(isTemplateInstantiation())),
4805 hasAncestor(cxxRecordDecl(unless(isTemplateInstantiation())))))));
4806}
4807
4808TEST(HasAncestor, ImplicitArrayCopyCtorDeclRefExpr) {
4809 EXPECT_TRUE(matches("struct MyClass {\n"
4810 " int c[1];\n"
4811 " static MyClass Create() { return MyClass(); }\n"
4812 "};",
4813 declRefExpr(to(decl(hasAncestor(decl()))))));
4814}
4815
4816TEST(HasAncestor, AnonymousUnionMemberExpr) {
4817 EXPECT_TRUE(matches("int F() {\n"
4818 " union { int i; };\n"
4819 " return i;\n"
4820 "}\n",
4821 memberExpr(member(hasAncestor(decl())))));
4822 EXPECT_TRUE(matches("void f() {\n"
4823 " struct {\n"
4824 " struct { int a; int b; };\n"
4825 " } s;\n"
4826 " s.a = 4;\n"
4827 "}\n",
4828 memberExpr(member(hasAncestor(decl())))));
4829 EXPECT_TRUE(matches("void f() {\n"
4830 " struct {\n"
4831 " struct { int a; int b; };\n"
4832 " } s;\n"
4833 " s.a = 4;\n"
4834 "}\n",
4835 declRefExpr(to(decl(hasAncestor(decl()))))));
4836}
4837TEST(HasAncestor, NonParmDependentTemplateParmVarDeclRefExpr) {
4838 EXPECT_TRUE(matches("struct PartitionAllocator {\n"
4839 " template<typename T>\n"
4840 " static int quantizedSize(int count) {\n"
4841 " return count;\n"
4842 " }\n"
4843 " void f() { quantizedSize<int>(10); }\n"
4844 "};",
4845 declRefExpr(to(decl(hasAncestor(decl()))))));
4846}
4847
4848TEST(HasAncestor, AddressOfExplicitSpecializationFunction) {
4849 EXPECT_TRUE(matches("template <class T> void f();\n"
4850 "template <> void f<int>();\n"
4851 "void (*get_f())() { return f<int>; }\n",
4852 declRefExpr(to(decl(hasAncestor(decl()))))));
4853}
4854
4855TEST(HasParent, MatchesAllParents) {
4856 EXPECT_TRUE(matches(
4857 "template <typename T> struct C { static void f() { 42; } };"
4858 "void t() { C<int>::f(); }",
4859 integerLiteral(
4860 equals(42),
4861 hasParent(compoundStmt(hasParent(functionDecl(
4862 hasParent(cxxRecordDecl(isTemplateInstantiation())))))))));
4863 EXPECT_TRUE(
4864 matches("template <typename T> struct C { static void f() { 42; } };"
4865 "void t() { C<int>::f(); }",
4866 integerLiteral(
4867 equals(42),
4868 hasParent(compoundStmt(hasParent(functionDecl(hasParent(
4869 cxxRecordDecl(unless(isTemplateInstantiation()))))))))));
4870 EXPECT_TRUE(matches(
4871 "template <typename T> struct C { static void f() { 42; } };"
4872 "void t() { C<int>::f(); }",
4873 integerLiteral(equals(42),
4874 hasParent(compoundStmt(
4875 allOf(hasParent(functionDecl(hasParent(
4876 cxxRecordDecl(isTemplateInstantiation())))),
4877 hasParent(functionDecl(hasParent(cxxRecordDecl(
4878 unless(isTemplateInstantiation())))))))))));
4879 EXPECT_TRUE(
4880 notMatches("template <typename T> struct C { static void f() {} };"
4881 "void t() { C<int>::f(); }",
4882 compoundStmt(hasParent(recordDecl()))));
4883}
4884
4885TEST(HasParent, NoDuplicateParents) {
4886 class HasDuplicateParents : public BoundNodesCallback {
4887 public:
4888 bool run(const BoundNodes *Nodes) override { return false; }
4889 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
4890 const Stmt *Node = Nodes->getNodeAs<Stmt>("node");
4891 std::set<const void *> Parents;
4892 for (const auto &Parent : Context->getParents(*Node)) {
4893 if (!Parents.insert(Parent.getMemoizationData()).second) {
4894 return true;
4895 }
4896 }
4897 return false;
4898 }
4899 };
4900 EXPECT_FALSE(matchAndVerifyResultTrue(
4901 "template <typename T> int Foo() { return 1 + 2; }\n"
4902 "int x = Foo<int>() + Foo<unsigned>();",
4903 stmt().bind("node"), std::make_unique<HasDuplicateParents>()));
4904}
4905
4906TEST(TypeMatching, PointeeTypes) {
4907 EXPECT_TRUE(matches("int b; int &a = b;",
4908 referenceType(pointee(builtinType()))));
4909 EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType()))));
4910
4911 EXPECT_TRUE(matches("int *a;",
4912 loc(pointerType(pointee(builtinType())))));
4913
4914 EXPECT_TRUE(matches(
4915 "int const *A;",
4916 pointerType(pointee(isConstQualified(), builtinType()))));
4917 EXPECT_TRUE(notMatches(
4918 "int *A;",
4919 pointerType(pointee(isConstQualified(), builtinType()))));
4920}
4921
4922TEST(ElaboratedTypeNarrowing, hasQualifier) {
4923 EXPECT_TRUE(matches(
4924 "namespace N {"
4925 " namespace M {"
4926 " class D {};"
4927 " }"
4928 "}"
4929 "N::M::D d;",
4930 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
4931 EXPECT_TRUE(notMatches(
4932 "namespace M {"
4933 " class D {};"
4934 "}"
4935 "M::D d;",
4936 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
4937 EXPECT_TRUE(notMatches(
4938 "struct D {"
4939 "} d;",
4940 elaboratedType(hasQualifier(nestedNameSpecifier()))));
4941}
4942
4943TEST(ElaboratedTypeNarrowing, namesType) {
4944 EXPECT_TRUE(matches(
4945 "namespace N {"
4946 " namespace M {"
4947 " class D {};"
4948 " }"
4949 "}"
4950 "N::M::D d;",
4951 elaboratedType(elaboratedType(namesType(recordType(
4952 hasDeclaration(namedDecl(hasName("D")))))))));
4953 EXPECT_TRUE(notMatches(
4954 "namespace M {"
4955 " class D {};"
4956 "}"
4957 "M::D d;",
4958 elaboratedType(elaboratedType(namesType(typedefType())))));
4959}
4960
4961TEST(NNS, BindsNestedNameSpecifiers) {
4962 EXPECT_TRUE(matchAndVerifyResultTrue(
4963 "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
4964 nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
4965 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>(
4966 "nns", "ns::struct E::")));
4967}
4968
4969TEST(NNS, BindsNestedNameSpecifierLocs) {
4970 EXPECT_TRUE(matchAndVerifyResultTrue(
4971 "namespace ns { struct B {}; } ns::B b;",
4972 loc(nestedNameSpecifier()).bind("loc"),
4973 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("loc", 1)));
4974}
4975
4976TEST(NNS, DescendantsOfNestedNameSpecifiers) {
4977 StringRef Fragment =
4978 "namespace a { struct A { struct B { struct C {}; }; }; };"
4979 "void f() { a::A::B::C c; }";
4980 EXPECT_TRUE(matches(
4981 Fragment,
4982 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
4983 hasDescendant(nestedNameSpecifier(
4984 specifiesNamespace(hasName("a")))))));
4985 EXPECT_TRUE(notMatches(
4986 Fragment,
4987 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
4988 has(nestedNameSpecifier(
4989 specifiesNamespace(hasName("a")))))));
4990 EXPECT_TRUE(matches(
4991 Fragment,
4992 nestedNameSpecifier(specifiesType(asString("struct a::A")),
4993 has(nestedNameSpecifier(
4994 specifiesNamespace(hasName("a")))))));
4995
4996 // Not really useful because a NestedNameSpecifier can af at most one child,
4997 // but to complete the interface.
4998 EXPECT_TRUE(matchAndVerifyResultTrue(
4999 Fragment,
5000 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5001 forEach(nestedNameSpecifier().bind("x"))),
5002 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("x", 1)));
5003}
5004
5005TEST(NNS, NestedNameSpecifiersAsDescendants) {
5006 StringRef Fragment =
5007 "namespace a { struct A { struct B { struct C {}; }; }; };"
5008 "void f() { a::A::B::C c; }";
5009 EXPECT_TRUE(matches(
5010 Fragment,
5011 decl(hasDescendant(nestedNameSpecifier(specifiesType(
5012 asString("struct a::A")))))));
5013 EXPECT_TRUE(matchAndVerifyResultTrue(
5014 Fragment,
5015 functionDecl(hasName("f"),
5016 forEachDescendant(nestedNameSpecifier().bind("x"))),
5017 // Nested names: a, a::A and a::A::B.
5018 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("x", 3)));
5019}
5020
5021TEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) {
5022 StringRef Fragment =
5023 "namespace a { struct A { struct B { struct C {}; }; }; };"
5024 "void f() { a::A::B::C c; }";
5025 EXPECT_TRUE(matches(
5026 Fragment,
5027 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5028 hasDescendant(loc(nestedNameSpecifier(
5029 specifiesNamespace(hasName("a"))))))));
5030 EXPECT_TRUE(notMatches(
5031 Fragment,
5032 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5033 has(loc(nestedNameSpecifier(
5034 specifiesNamespace(hasName("a"))))))));
5035 EXPECT_TRUE(matches(
5036 Fragment,
5037 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))),
5038 has(loc(nestedNameSpecifier(
5039 specifiesNamespace(hasName("a"))))))));
5040
5041 EXPECT_TRUE(matchAndVerifyResultTrue(
5042 Fragment,
5043 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5044 forEach(nestedNameSpecifierLoc().bind("x"))),
5045 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("x", 1)));
5046}
5047
5048TEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) {
5049 StringRef Fragment =
5050 "namespace a { struct A { struct B { struct C {}; }; }; };"
5051 "void f() { a::A::B::C c; }";
5052 EXPECT_TRUE(matches(
5053 Fragment,
5054 decl(hasDescendant(loc(nestedNameSpecifier(specifiesType(
5055 asString("struct a::A"))))))));
5056 EXPECT_TRUE(matchAndVerifyResultTrue(
5057 Fragment,
5058 functionDecl(hasName("f"),
5059 forEachDescendant(nestedNameSpecifierLoc().bind("x"))),
5060 // Nested names: a, a::A and a::A::B.
5061 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("x", 3)));
5062}
5063template <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
5064public:
5065 VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher,
5066 StringRef InnerId)
5067 : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {
5068 }
5069
5070 bool run(const BoundNodes *Nodes) override { return false; }
5071
5072 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
5073 const T *Node = Nodes->getNodeAs<T>(Id);
5074 return selectFirst<T>(InnerId, match(InnerMatcher, *Node, *Context)) !=
5075 nullptr;
5076 }
5077private:
5078 std::string Id;
5079 internal::Matcher<T> InnerMatcher;
5080 std::string InnerId;
5081};
5082
5083TEST(MatchFinder, CanMatchDeclarationsRecursively) {
5084 EXPECT_TRUE(matchAndVerifyResultTrue(
5085 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5086 std::make_unique<VerifyMatchOnNode<Decl>>(
5087 "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))),
5088 "Y")));
5089 EXPECT_TRUE(matchAndVerifyResultFalse(
5090 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5091 std::make_unique<VerifyMatchOnNode<Decl>>(
5092 "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))),
5093 "Z")));
5094}
5095
5096TEST(MatchFinder, CanMatchStatementsRecursively) {
5097 EXPECT_TRUE(matchAndVerifyResultTrue(
5098 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
5099 std::make_unique<VerifyMatchOnNode<Stmt>>(
5100 "if", stmt(hasDescendant(forStmt().bind("for"))), "for")));
5101 EXPECT_TRUE(matchAndVerifyResultFalse(
5102 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
5103 std::make_unique<VerifyMatchOnNode<Stmt>>(
5104 "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl")));
5105}
5106
5107TEST(MatchFinder, CanMatchSingleNodesRecursively) {
5108 EXPECT_TRUE(matchAndVerifyResultTrue(
5109 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5110 std::make_unique<VerifyMatchOnNode<Decl>>(
5111 "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y")));
5112 EXPECT_TRUE(matchAndVerifyResultFalse(
5113 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5114 std::make_unique<VerifyMatchOnNode<Decl>>(
5115 "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z")));
5116}
5117
5118TEST(StatementMatcher, HasReturnValue) {
5119 StatementMatcher RetVal = returnStmt(hasReturnValue(binaryOperator()));
5120 EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal));
5121 EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal));
5122 EXPECT_FALSE(matches("void F() { return; }", RetVal));
5123}
5124
5125TEST(StatementMatcher, ForFunction) {
5126 StringRef CppString1 = "struct PosVec {"
5127 " PosVec& operator=(const PosVec&) {"
5128 " auto x = [] { return 1; };"
5129 " return *this;"
5130 " }"
5131 "};";
5132 StringRef CppString2 = "void F() {"
5133 " struct S {"
5134 " void F2() {"
5135 " return;"
5136 " }"
5137 " };"
5138 "}";
5139 EXPECT_TRUE(
5140 matches(
5141 CppString1,
5142 returnStmt(forFunction(hasName("operator=")),
5143 has(unaryOperator(hasOperatorName("*"))))));
5144 EXPECT_TRUE(
5145 notMatches(
5146 CppString1,
5147 returnStmt(forFunction(hasName("operator=")),
5148 has(integerLiteral()))));
5149 EXPECT_TRUE(
5150 matches(
5151 CppString1,
5152 returnStmt(forFunction(hasName("operator()")),
5153 has(integerLiteral()))));
5154 EXPECT_TRUE(matches(CppString2, returnStmt(forFunction(hasName("F2")))));
5155 EXPECT_TRUE(notMatches(CppString2, returnStmt(forFunction(hasName("F")))));
5156}
5157
5158TEST(Matcher, ForEachOverriden) {
5159 const auto ForEachOverriddenInClass = [](const char *ClassName) {
5160 return cxxMethodDecl(ofClass(hasName(ClassName)), isVirtual(),
5161 forEachOverridden(cxxMethodDecl().bind("overridden")))
5162 .bind("override");
5163 };
5164 static const char Code1[] = "class A { virtual void f(); };"
5165 "class B : public A { void f(); };"
5166 "class C : public B { void f(); };";
5167 // C::f overrides A::f.
5168 EXPECT_TRUE(matchAndVerifyResultTrue(
5169 Code1, ForEachOverriddenInClass("C"),
5170 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 1)));
5171 EXPECT_TRUE(matchAndVerifyResultTrue(
5172 Code1, ForEachOverriddenInClass("C"),
5173 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f",
5174 1)));
5175 // B::f overrides A::f.
5176 EXPECT_TRUE(matchAndVerifyResultTrue(
5177 Code1, ForEachOverriddenInClass("B"),
5178 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 1)));
5179 EXPECT_TRUE(matchAndVerifyResultTrue(
5180 Code1, ForEachOverriddenInClass("B"),
5181 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f",
5182 1)));
5183 // A::f overrides nothing.
5184 EXPECT_TRUE(notMatches(Code1, ForEachOverriddenInClass("A")));
5185
5186 static const char Code2[] =
5187 "class A1 { virtual void f(); };"
5188 "class A2 { virtual void f(); };"
5189 "class B : public A1, public A2 { void f(); };";
5190 // B::f overrides A1::f and A2::f. This produces two matches.
5191 EXPECT_TRUE(matchAndVerifyResultTrue(
5192 Code2, ForEachOverriddenInClass("B"),
5193 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 2)));
5194 EXPECT_TRUE(matchAndVerifyResultTrue(
5195 Code2, ForEachOverriddenInClass("B"),
5196 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f",
5197 2)));
5198 // A1::f overrides nothing.
5199 EXPECT_TRUE(notMatches(Code2, ForEachOverriddenInClass("A1")));
5200}
5201
5202TEST(Matcher, HasAnyDeclaration) {
5203 StringRef Fragment = "void foo(int p1);"
5204 "void foo(int *p2);"
5205 "void bar(int p3);"
5206 "template <typename T> void baz(T t) { foo(t); }";
5207
5208 EXPECT_TRUE(
5209 matches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl(
5210 hasParameter(0, parmVarDecl(hasName("p1"))))))));
5211 EXPECT_TRUE(
5212 matches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl(
5213 hasParameter(0, parmVarDecl(hasName("p2"))))))));
5214 EXPECT_TRUE(
5215 notMatches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl(
5216 hasParameter(0, parmVarDecl(hasName("p3"))))))));
5217 EXPECT_TRUE(notMatches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(
5218 functionDecl(hasName("bar"))))));
5219}
5220
5221TEST(SubstTemplateTypeParmType, HasReplacementType) {
5222 StringRef Fragment = "template<typename T>"
5223 "double F(T t);"
5224 "int i;"
5225 "double j = F(i);";
5226 EXPECT_TRUE(matches(Fragment, substTemplateTypeParmType(hasReplacementType(
5227 qualType(asString("int"))))));
5228 EXPECT_TRUE(notMatches(Fragment, substTemplateTypeParmType(hasReplacementType(
5229 qualType(asString("double"))))));
5230 EXPECT_TRUE(
5231 notMatches("template<int N>"
5232 "double F();"
5233 "double j = F<5>();",
5234 substTemplateTypeParmType(hasReplacementType(qualType()))));
5235}
5236
5237TEST(ClassTemplateSpecializationDecl, HasSpecializedTemplate) {
5238 auto Matcher = classTemplateSpecializationDecl(
5239 hasSpecializedTemplate(classTemplateDecl()));
5240 EXPECT_TRUE(
5241 matches("template<typename T> class A {}; typedef A<int> B;", Matcher));
5242 EXPECT_TRUE(notMatches("template<typename T> class A {};", Matcher));
5243}
5244
5245TEST(CXXNewExpr, Array) {
5246 StatementMatcher NewArray = cxxNewExpr(isArray());
5247
5248 EXPECT_TRUE(matches("void foo() { int *Ptr = new int[10]; }", NewArray));
5249 EXPECT_TRUE(notMatches("void foo() { int *Ptr = new int; }", NewArray));
5250
5251 StatementMatcher NewArraySize10 =
5252 cxxNewExpr(hasArraySize(integerLiteral(equals(10))));
5253 EXPECT_TRUE(
5254 matches("void foo() { int *Ptr = new int[10]; }", NewArraySize10));
5255 EXPECT_TRUE(
5256 notMatches("void foo() { int *Ptr = new int[20]; }", NewArraySize10));
5257}
5258
5259TEST(CXXNewExpr, PlacementArgs) {
5260 StatementMatcher IsPlacementNew = cxxNewExpr(hasAnyPlacementArg(anything()));
5261
5262 EXPECT_TRUE(matches(R"(
5263 void* operator new(decltype(sizeof(void*)), void*);
5264 int *foo(void* Storage) {
5265 return new (Storage) int;
5266 })",
5267 IsPlacementNew));
5268
5269 EXPECT_TRUE(matches(R"(
5270 void* operator new(decltype(sizeof(void*)), void*, unsigned);
5271 int *foo(void* Storage) {
5272 return new (Storage, 16) int;
5273 })",
5274 cxxNewExpr(hasPlacementArg(
5275 1, ignoringImpCasts(integerLiteral(equals(16)))))));
5276
5277 EXPECT_TRUE(notMatches(R"(
5278 void* operator new(decltype(sizeof(void*)), void*);
5279 int *foo(void* Storage) {
5280 return new int;
5281 })",
5282 IsPlacementNew));
5283}
5284
5285} // namespace ast_matchers
5286} // namespace clang
5287